6666802 Cannot copy >1023 byte readonly file from Vista client to Solaris CIFS share
authoras200622
Mon, 14 Apr 2008 10:40:32 -0700
changeset 6432 98715880dd9e
parent 6431 3ff4f84a1ced
child 6433 b80c8a854640
6666802 Cannot copy >1023 byte readonly file from Vista client to Solaris CIFS share 6669427 Intermittently seeing incorrect file sizes in Mac Finder 6671224 Nic monitoring needs to be part of libsmb 6671269 ntsid.h cleanup 6671618 smbstat: kstat lookups failed for smb 6673567 smbd crashes in smb_lgrp_free 6674636 smb_fsop_frlock() needs to use single common CIFS pid smb_ct.cc_pid 6677633 unix_to_nt_time() panic 6679147 zfs_znode_free while running stress tests. 6680694 smbadm CLI unnecessarily prompts users for overriding domain configuration 6681178 nbl_lock_conflict() return code should not be returned directly from smb_fsop_read()/write() 6684686 smbadm join CLI doesn't always create all the necessary attributes in a system's AD computer object 6687645 The kernel configuration is not totally updated when parameters change.
usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c
usr/src/cmd/smbsrv/Makefile.smbsrv.defs
usr/src/cmd/smbsrv/smbadm/Makefile
usr/src/cmd/smbsrv/smbadm/smbadm.c
usr/src/cmd/smbsrv/smbd/Makefile
usr/src/cmd/smbsrv/smbd/smbd.h
usr/src/cmd/smbsrv/smbd/smbd_door_ops.c
usr/src/cmd/smbsrv/smbd/smbd_join.c
usr/src/cmd/smbsrv/smbd/smbd_logon.c
usr/src/cmd/smbsrv/smbd/smbd_main.c
usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c
usr/src/cmd/smbsrv/smbd/smbd_nicmon.c
usr/src/cmd/smbsrv/smbstat/smbstat.c
usr/src/common/smbsrv/smb_sid.c
usr/src/common/smbsrv/smb_string.c
usr/src/common/smbsrv/smb_token.c
usr/src/common/smbsrv/smb_token_xdr.c
usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c
usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c
usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c
usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
usr/src/lib/smbsrv/libmlsvc/common/samlib.c
usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c
usr/src/lib/smbsrv/libmlsvc/common/secdb.c
usr/src/lib/smbsrv/libsmb/Makefile.com
usr/src/lib/smbsrv/libsmb/common/libsmb.h
usr/src/lib/smbsrv/libsmb/common/mapfile-vers
usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c
usr/src/lib/smbsrv/libsmb/common/smb_auth.c
usr/src/lib/smbsrv/libsmb/common/smb_domain.c
usr/src/lib/smbsrv/libsmb/common/smb_idmap.c
usr/src/lib/smbsrv/libsmb/common/smb_info.c
usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
usr/src/lib/smbsrv/libsmb/common/smb_nicmon.c
usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c
usr/src/lib/smbsrv/libsmb/common/smb_wksids.c
usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
usr/src/pkgdefs/etc/exception_list_i386
usr/src/pkgdefs/etc/exception_list_sparc
usr/src/uts/common/fs/smbsrv/smb_acl.c
usr/src/uts/common/fs/smbsrv/smb_common_open.c
usr/src/uts/common/fs/smbsrv/smb_common_transact.c
usr/src/uts/common/fs/smbsrv/smb_common_tree.c
usr/src/uts/common/fs/smbsrv/smb_dispatch.c
usr/src/uts/common/fs/smbsrv/smb_find.c
usr/src/uts/common/fs/smbsrv/smb_fsops.c
usr/src/uts/common/fs/smbsrv/smb_kdoor_clnt.c
usr/src/uts/common/fs/smbsrv/smb_kdoor_ops.c
usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c
usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c
usr/src/uts/common/fs/smbsrv/smb_node.c
usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c
usr/src/uts/common/fs/smbsrv/smb_ofile.c
usr/src/uts/common/fs/smbsrv/smb_query_information.c
usr/src/uts/common/fs/smbsrv/smb_query_information2.c
usr/src/uts/common/fs/smbsrv/smb_read.c
usr/src/uts/common/fs/smbsrv/smb_sd.c
usr/src/uts/common/fs/smbsrv/smb_search.c
usr/src/uts/common/fs/smbsrv/smb_server.c
usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
usr/src/uts/common/fs/smbsrv/smb_util.c
usr/src/uts/common/fs/smbsrv/smb_vops.c
usr/src/uts/common/fs/smbsrv/smb_winpipe.c
usr/src/uts/common/smbsrv/Makefile
usr/src/uts/common/smbsrv/lsalib.h
usr/src/uts/common/smbsrv/mlsvc.h
usr/src/uts/common/smbsrv/mlsvc_util.h
usr/src/uts/common/smbsrv/ntsid.h
usr/src/uts/common/smbsrv/smb_fsops.h
usr/src/uts/common/smbsrv/smb_idmap.h
usr/src/uts/common/smbsrv/smb_kproto.h
usr/src/uts/common/smbsrv/smb_kstat.h
usr/src/uts/common/smbsrv/smb_ktypes.h
usr/src/uts/common/smbsrv/smb_sid.h
usr/src/uts/common/smbsrv/smb_token.h
--- a/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c	Mon Apr 14 10:40:32 2008 -0700
@@ -31,243 +31,1254 @@
 #include <smbsrv/mlsvc.h>
 #include <smbsrv/smb_ktypes.h>
 
-#define	SMB_DCMD_INDENT		4
+#define	SMB_DCMD_INDENT		2
+#define	ACE_TYPE_TABLEN		(ACE_ALL_TYPES + 1)
+#define	ACE_TYPE_ENTRY(_v_)	{_v_, #_v_}
+#define	SMB_COM_ENTRY(_v_, _x_)	{#_v_, _x_}
+
+#define	SMB_MDB_MAX_OPTS	10
+
+#define	SMB_OPT_SERVER		0x00000001
+#define	SMB_OPT_VFS		0x00000002
+#define	SMB_OPT_SESSION		0x00000004
+#define	SMB_OPT_REQUEST		0x00000008
+#define	SMB_OPT_USER		0x00000010
+#define	SMB_OPT_TREE		0x00000020
+#define	SMB_OPT_OFILE		0x00000040
+#define	SMB_OPT_ODIR		0x00000080
+#define	SMB_OPT_WALK		0x00000100
+#define	SMB_OPT_VERBOSE		0x00000200
+#define	SMB_OPT_ALL_OBJ		0x000000FF
 
-static int smb_session_walk_init(mdb_walk_state_t *, size_t);
-static void smb_server_lookup_state_str(smb_server_state_t, char *, int);
+/*
+ * Structure associating an ACE type to a string.
+ */
+typedef struct {
+	uint8_t		ace_type_value;
+	const char	*ace_type_sting;
+} ace_type_entry_t;
+
+/*
+ * Structure containing strings describing an SMB command.
+ */
+typedef struct {
+	const char	*smb_com;
+	const char	*smb_andx;
+} smb_com_entry_t;
+
+/*
+ * Structure describing an object to be expanded (displayed).
+ */
+typedef struct {
+	uint_t		ex_mask;
+	size_t		ex_offset;
+	const char	*ex_dcmd;
+	const char	*ex_name;
+} smb_exp_t;
 
 /*
- * Initialize the smb_session_t walker by reading the value of smb_info
- * object in the kernel's symbol table. Only global walk supported.
+ * List of supported options. Ther order has the match the bits SMB_OPT_xxx.
  */
-static int
-smb_session_nbt_rdy_walk_init(mdb_walk_state_t *wsp)
-{
-	return (smb_session_walk_init(wsp,
-	    offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_rdy.lst)));
-}
-
-static int
-smb_session_nbt_act_walk_init(mdb_walk_state_t *wsp)
+static const char *smb_opts[SMB_MDB_MAX_OPTS] =
 {
-	return (smb_session_walk_init(wsp,
-	    offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_act.lst)));
-}
-
-static int
-smb_session_tcp_rdy_walk_init(mdb_walk_state_t *wsp)
-{
-	return (smb_session_walk_init(wsp,
-	    offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_rdy.lst)));
-}
-
-static int
-smb_session_tcp_act_walk_init(mdb_walk_state_t *wsp)
-{
-	return (smb_session_walk_init(wsp,
-	    offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_act.lst)));
-}
+	"-s", "-m", "-e", "-r", "-u", "-t", "-f", "-d", "-w", "-v"
+};
 
-static int
-smb_session_walk_init(mdb_walk_state_t *wsp, size_t offset)
+static smb_com_entry_t	smb_com[256] =
 {
-	if (wsp->walk_addr) {
-		mdb_printf("smb_session walk only supports global walks\n");
-		return (WALK_ERR);
-	}
-
-	if (mdb_readvar(&wsp->walk_addr, "smb_server") == -1) {
-		mdb_warn("failed to read 'smb_server'");
-		return (WALK_ERR);
-	}
+	SMB_COM_ENTRY(SMB_COM_CREATE_DIRECTORY, "No"),
+	SMB_COM_ENTRY(SMB_COM_DELETE_DIRECTORY, "No"),
+	SMB_COM_ENTRY(SMB_COM_OPEN, "No"),
+	SMB_COM_ENTRY(SMB_COM_CREATE, "No"),
+	SMB_COM_ENTRY(SMB_COM_CLOSE, "No"),
+	SMB_COM_ENTRY(SMB_COM_FLUSH, "No"),
+	SMB_COM_ENTRY(SMB_COM_DELETE, "No"),
+	SMB_COM_ENTRY(SMB_COM_RENAME, "No"),
+	SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION, "No"),
+	SMB_COM_ENTRY(SMB_COM_SET_INFORMATION, "No"),
+	SMB_COM_ENTRY(SMB_COM_READ, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE, "No"),
+	SMB_COM_ENTRY(SMB_COM_LOCK_BYTE_RANGE, "No"),
+	SMB_COM_ENTRY(SMB_COM_UNLOCK_BYTE_RANGE, "No"),
+	SMB_COM_ENTRY(SMB_COM_CREATE_TEMPORARY, "No"),
+	SMB_COM_ENTRY(SMB_COM_CREATE_NEW, "No"),
+	SMB_COM_ENTRY(SMB_COM_CHECK_DIRECTORY, "No"),
+	SMB_COM_ENTRY(SMB_COM_PROCESS_EXIT, "No"),
+	SMB_COM_ENTRY(SMB_COM_SEEK, "No"),
+	SMB_COM_ENTRY(SMB_COM_LOCK_AND_READ, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_AND_UNLOCK, "No"),
+	SMB_COM_ENTRY(0x15, "?"),
+	SMB_COM_ENTRY(0x16, "?"),
+	SMB_COM_ENTRY(0x17, "?"),
+	SMB_COM_ENTRY(0x18, "?"),
+	SMB_COM_ENTRY(0x19, "?"),
+	SMB_COM_ENTRY(SMB_COM_READ_RAW, "No"),
+	SMB_COM_ENTRY(SMB_COM_READ_MPX, "No"),
+	SMB_COM_ENTRY(SMB_COM_READ_MPX_SECONDARY, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_RAW, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_MPX, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_MPX_SECONDARY, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_COMPLETE, "No"),
+	SMB_COM_ENTRY(SMB_COM_QUERY_SERVER, "No"),
+	SMB_COM_ENTRY(SMB_COM_SET_INFORMATION2, "No"),
+	SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION2, "No"),
+	SMB_COM_ENTRY(SMB_COM_LOCKING_ANDX, "No"),
+	SMB_COM_ENTRY(SMB_COM_TRANSACTION, "No"),
+	SMB_COM_ENTRY(SMB_COM_TRANSACTION_SECONDARY, "No"),
+	SMB_COM_ENTRY(SMB_COM_IOCTL, "No"),
+	SMB_COM_ENTRY(SMB_COM_IOCTL_SECONDARY, "No"),
+	SMB_COM_ENTRY(SMB_COM_COPY, "No"),
+	SMB_COM_ENTRY(SMB_COM_MOVE, "No"),
+	SMB_COM_ENTRY(SMB_COM_ECHO, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_AND_CLOSE, "No"),
+	SMB_COM_ENTRY(SMB_COM_OPEN_ANDX, "No"),
+	SMB_COM_ENTRY(SMB_COM_READ_ANDX, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_ANDX, "No"),
+	SMB_COM_ENTRY(SMB_COM_NEW_FILE_SIZE, "No"),
+	SMB_COM_ENTRY(SMB_COM_CLOSE_AND_TREE_DISC, "No"),
+	SMB_COM_ENTRY(SMB_COM_TRANSACTION2, "No"),
+	SMB_COM_ENTRY(SMB_COM_TRANSACTION2_SECONDARY, "No"),
+	SMB_COM_ENTRY(SMB_COM_FIND_CLOSE2, "No"),
+	SMB_COM_ENTRY(SMB_COM_FIND_NOTIFY_CLOSE, "No"),
+	SMB_COM_ENTRY(0x36, "?"),
+	SMB_COM_ENTRY(0x37, "?"),
+	SMB_COM_ENTRY(0x38, "?"),
+	SMB_COM_ENTRY(0x39, "?"),
+	SMB_COM_ENTRY(0x3A, "?"),
+	SMB_COM_ENTRY(0x3B, "?"),
+	SMB_COM_ENTRY(0x3C, "?"),
+	SMB_COM_ENTRY(0x3D, "?"),
+	SMB_COM_ENTRY(0x3E, "?"),
+	SMB_COM_ENTRY(0x3F, "?"),
+	SMB_COM_ENTRY(0x40, "?"),
+	SMB_COM_ENTRY(0x41, "?"),
+	SMB_COM_ENTRY(0x42, "?"),
+	SMB_COM_ENTRY(0x43, "?"),
+	SMB_COM_ENTRY(0x44, "?"),
+	SMB_COM_ENTRY(0x45, "?"),
+	SMB_COM_ENTRY(0x46, "?"),
+	SMB_COM_ENTRY(0x47, "?"),
+	SMB_COM_ENTRY(0x48, "?"),
+	SMB_COM_ENTRY(0x49, "?"),
+	SMB_COM_ENTRY(0x4A, "?"),
+	SMB_COM_ENTRY(0x4B, "?"),
+	SMB_COM_ENTRY(0x4C, "?"),
+	SMB_COM_ENTRY(0x4D, "?"),
+	SMB_COM_ENTRY(0x4E, "?"),
+	SMB_COM_ENTRY(0x4F, "?"),
+	SMB_COM_ENTRY(0x50, "?"),
+	SMB_COM_ENTRY(0x51, "?"),
+	SMB_COM_ENTRY(0x52, "?"),
+	SMB_COM_ENTRY(0x53, "?"),
+	SMB_COM_ENTRY(0x54, "?"),
+	SMB_COM_ENTRY(0x55, "?"),
+	SMB_COM_ENTRY(0x56, "?"),
+	SMB_COM_ENTRY(0x57, "?"),
+	SMB_COM_ENTRY(0x58, "?"),
+	SMB_COM_ENTRY(0x59, "?"),
+	SMB_COM_ENTRY(0x5A, "?"),
+	SMB_COM_ENTRY(0x5B, "?"),
+	SMB_COM_ENTRY(0x5C, "?"),
+	SMB_COM_ENTRY(0x5D, "?"),
+	SMB_COM_ENTRY(0x5E, "?"),
+	SMB_COM_ENTRY(0x5F, "?"),
+	SMB_COM_ENTRY(0x60, "?"),
+	SMB_COM_ENTRY(0x61, "?"),
+	SMB_COM_ENTRY(0x62, "?"),
+	SMB_COM_ENTRY(0x63, "?"),
+	SMB_COM_ENTRY(0x64, "?"),
+	SMB_COM_ENTRY(0x65, "?"),
+	SMB_COM_ENTRY(0x66, "?"),
+	SMB_COM_ENTRY(0x67, "?"),
+	SMB_COM_ENTRY(0x68, "?"),
+	SMB_COM_ENTRY(0x69, "?"),
+	SMB_COM_ENTRY(0x6A, "?"),
+	SMB_COM_ENTRY(0x6B, "?"),
+	SMB_COM_ENTRY(0x6C, "?"),
+	SMB_COM_ENTRY(0x6D, "?"),
+	SMB_COM_ENTRY(0x6E, "?"),
+	SMB_COM_ENTRY(0x6F, "?"),
+	SMB_COM_ENTRY(SMB_COM_TREE_CONNECT, "No"),
+	SMB_COM_ENTRY(SMB_COM_TREE_DISCONNECT, "No"),
+	SMB_COM_ENTRY(SMB_COM_NEGOTIATE, "No"),
+	SMB_COM_ENTRY(SMB_COM_SESSION_SETUP_ANDX, "No"),
+	SMB_COM_ENTRY(SMB_COM_LOGOFF_ANDX, "No"),
+	SMB_COM_ENTRY(SMB_COM_TREE_CONNECT_ANDX, "No"),
+	SMB_COM_ENTRY(0x76, "?"),
+	SMB_COM_ENTRY(0x77, "?"),
+	SMB_COM_ENTRY(0x78, "?"),
+	SMB_COM_ENTRY(0x79, "?"),
+	SMB_COM_ENTRY(0x7A, "?"),
+	SMB_COM_ENTRY(0x7B, "?"),
+	SMB_COM_ENTRY(0x7C, "?"),
+	SMB_COM_ENTRY(0x7D, "?"),
+	SMB_COM_ENTRY(0x7E, "?"),
+	SMB_COM_ENTRY(0x7F, "?"),
+	SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION_DISK, "No"),
+	SMB_COM_ENTRY(SMB_COM_SEARCH, "No"),
+	SMB_COM_ENTRY(SMB_COM_FIND, "No"),
+	SMB_COM_ENTRY(SMB_COM_FIND_UNIQUE, "No"),
+	SMB_COM_ENTRY(SMB_COM_FIND_CLOSE, "No"),
+	SMB_COM_ENTRY(0x85, "?"),
+	SMB_COM_ENTRY(0x86, "?"),
+	SMB_COM_ENTRY(0x87, "?"),
+	SMB_COM_ENTRY(0x88, "?"),
+	SMB_COM_ENTRY(0x89, "?"),
+	SMB_COM_ENTRY(0x8A, "?"),
+	SMB_COM_ENTRY(0x8B, "?"),
+	SMB_COM_ENTRY(0x8C, "?"),
+	SMB_COM_ENTRY(0x8D, "?"),
+	SMB_COM_ENTRY(0x8E, "?"),
+	SMB_COM_ENTRY(0x8F, "?"),
+	SMB_COM_ENTRY(0x90, "?"),
+	SMB_COM_ENTRY(0x91, "?"),
+	SMB_COM_ENTRY(0x92, "?"),
+	SMB_COM_ENTRY(0x93, "?"),
+	SMB_COM_ENTRY(0x94, "?"),
+	SMB_COM_ENTRY(0x95, "?"),
+	SMB_COM_ENTRY(0x96, "?"),
+	SMB_COM_ENTRY(0x97, "?"),
+	SMB_COM_ENTRY(0x98, "?"),
+	SMB_COM_ENTRY(0x99, "?"),
+	SMB_COM_ENTRY(0x9A, "?"),
+	SMB_COM_ENTRY(0x9B, "?"),
+	SMB_COM_ENTRY(0x9C, "?"),
+	SMB_COM_ENTRY(0x9D, "?"),
+	SMB_COM_ENTRY(0x9E, "?"),
+	SMB_COM_ENTRY(0x9F, "?"),
+	SMB_COM_ENTRY(SMB_COM_NT_TRANSACT, "No"),
+	SMB_COM_ENTRY(SMB_COM_NT_TRANSACT_SECONDARY, "No"),
+	SMB_COM_ENTRY(SMB_COM_NT_CREATE_ANDX, "No"),
+	SMB_COM_ENTRY(SMB_COM_NT_CANCEL, "No"),
+	SMB_COM_ENTRY(SMB_COM_NT_RENAME, "No"),
+	SMB_COM_ENTRY(0xA6, "?"),
+	SMB_COM_ENTRY(0xA7, "?"),
+	SMB_COM_ENTRY(0xA8, "?"),
+	SMB_COM_ENTRY(0xA9, "?"),
+	SMB_COM_ENTRY(0xAA, "?"),
+	SMB_COM_ENTRY(0xAB, "?"),
+	SMB_COM_ENTRY(0xAC, "?"),
+	SMB_COM_ENTRY(0xAD, "?"),
+	SMB_COM_ENTRY(0xAE, "?"),
+	SMB_COM_ENTRY(0xAF, "?"),
+	SMB_COM_ENTRY(0xB0, "?"),
+	SMB_COM_ENTRY(0xB1, "?"),
+	SMB_COM_ENTRY(0xB2, "?"),
+	SMB_COM_ENTRY(0xB3, "?"),
+	SMB_COM_ENTRY(0xB4, "?"),
+	SMB_COM_ENTRY(0xB5, "?"),
+	SMB_COM_ENTRY(0xB6, "?"),
+	SMB_COM_ENTRY(0xB7, "?"),
+	SMB_COM_ENTRY(0xB8, "?"),
+	SMB_COM_ENTRY(0xB9, "?"),
+	SMB_COM_ENTRY(0xBA, "?"),
+	SMB_COM_ENTRY(0xBB, "?"),
+	SMB_COM_ENTRY(0xBC, "?"),
+	SMB_COM_ENTRY(0xBD, "?"),
+	SMB_COM_ENTRY(0xBE, "?"),
+	SMB_COM_ENTRY(0xBF, "?"),
+	SMB_COM_ENTRY(SMB_COM_OPEN_PRINT_FILE, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_PRINT_FILE, "No"),
+	SMB_COM_ENTRY(SMB_COM_CLOSE_PRINT_FILE, "No"),
+	SMB_COM_ENTRY(SMB_COM_GET_PRINT_QUEUE, "No"),
+	SMB_COM_ENTRY(0xC4, "?"),
+	SMB_COM_ENTRY(0xC5, "?"),
+	SMB_COM_ENTRY(0xC6, "?"),
+	SMB_COM_ENTRY(0xC7, "?"),
+	SMB_COM_ENTRY(0xC8, "?"),
+	SMB_COM_ENTRY(0xC9, "?"),
+	SMB_COM_ENTRY(0xCA, "?"),
+	SMB_COM_ENTRY(0xCB, "?"),
+	SMB_COM_ENTRY(0xCC, "?"),
+	SMB_COM_ENTRY(0xCD, "?"),
+	SMB_COM_ENTRY(0xCE, "?"),
+	SMB_COM_ENTRY(0xCF, "?"),
+	SMB_COM_ENTRY(0xD0, "?"),
+	SMB_COM_ENTRY(0xD1, "?"),
+	SMB_COM_ENTRY(0xD2, "?"),
+	SMB_COM_ENTRY(0xD3, "?"),
+	SMB_COM_ENTRY(0xD4, "?"),
+	SMB_COM_ENTRY(0xD5, "?"),
+	SMB_COM_ENTRY(0xD6, "?"),
+	SMB_COM_ENTRY(0xD7, "?"),
+	SMB_COM_ENTRY(SMB_COM_READ_BULK, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_BULK, "No"),
+	SMB_COM_ENTRY(SMB_COM_WRITE_BULK_DATA, "No"),
+	SMB_COM_ENTRY(0xDB, "?"),
+	SMB_COM_ENTRY(0xDC, "?"),
+	SMB_COM_ENTRY(0xDE, "?"),
+	SMB_COM_ENTRY(0xDF, "?"),
+	SMB_COM_ENTRY(0xE0, "?"),
+	SMB_COM_ENTRY(0xE1, "?"),
+	SMB_COM_ENTRY(0xE2, "?"),
+	SMB_COM_ENTRY(0xE3, "?"),
+	SMB_COM_ENTRY(0xE4, "?"),
+	SMB_COM_ENTRY(0xE5, "?"),
+	SMB_COM_ENTRY(0xE6, "?"),
+	SMB_COM_ENTRY(0xE7, "?"),
+	SMB_COM_ENTRY(0xE8, "?"),
+	SMB_COM_ENTRY(0xE9, "?"),
+	SMB_COM_ENTRY(0xEA, "?"),
+	SMB_COM_ENTRY(0xEB, "?"),
+	SMB_COM_ENTRY(0xEC, "?"),
+	SMB_COM_ENTRY(0xED, "?"),
+	SMB_COM_ENTRY(0xEE, "?"),
+	SMB_COM_ENTRY(0xEF, "?"),
+	SMB_COM_ENTRY(0xF0, "?"),
+	SMB_COM_ENTRY(0xF1, "?"),
+	SMB_COM_ENTRY(0xF2, "?"),
+	SMB_COM_ENTRY(0xF3, "?"),
+	SMB_COM_ENTRY(0xF4, "?"),
+	SMB_COM_ENTRY(0xF5, "?"),
+	SMB_COM_ENTRY(0xF6, "?"),
+	SMB_COM_ENTRY(0xF7, "?"),
+	SMB_COM_ENTRY(0xF8, "?"),
+	SMB_COM_ENTRY(0xF9, "?"),
+	SMB_COM_ENTRY(0xFA, "?"),
+	SMB_COM_ENTRY(0xFB, "?"),
+	SMB_COM_ENTRY(0xFC, "?"),
+	SMB_COM_ENTRY(0xFD, "?"),
+	SMB_COM_ENTRY(0xFE, "?"),
+	SMB_COM_ENTRY(0xFF, "?")
+};
 
-	if (wsp->walk_addr == 0) {
-		mdb_warn("failed to find an SMB server");
-		return (WALK_ERR);
-	}
-
-	wsp->walk_addr += offset;
+static int smb_dcmd_list(uintptr_t, uint_t, int, const mdb_arg_t *);
+static void smb_dcmd_list_help(void);
+static int smb_dcmd_server(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_dcmd_vfs(uintptr_t, uint_t, int, const mdb_arg_t *);
+static void smb_dcmd_session_help(void);
+static int smb_dcmd_session(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_dcmd_request(uintptr_t, uint_t, int, const mdb_arg_t *);
+static void smb_dcmd_user_help(void);
+static int smb_dcmd_user(uintptr_t, uint_t, int, const mdb_arg_t *);
+static void smb_dcmd_tree_help(void);
+static int smb_dcmd_tree(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_dcmd_odir(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_dcmd_ofile(uintptr_t, uint_t, int, const mdb_arg_t *);
+static void smb_node_help(void);
+static int smb_node(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_node_walk_init(mdb_walk_state_t *);
+static int smb_node_walk_step(mdb_walk_state_t *);
+static int smb_lock(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_stats(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_ace(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_ace_walk_init(mdb_walk_state_t *);
+static int smb_ace_walk_step(mdb_walk_state_t *);
+static int smb_acl(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_sd(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_sid(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_sid_print(uintptr_t);
+static int smb_fssd(uintptr_t, uint_t, int, const mdb_arg_t *);
+static int smb_dcmd_getopt(uint_t *, int, const mdb_arg_t *);
+static int smb_dcmd_setopt(uint_t, int, mdb_arg_t *);
+static int smb_obj_expand(uintptr_t, uint_t, const smb_exp_t *, ulong_t);
+static int smb_obj_list(const char *, uint_t, uint_t);
 
-	if (mdb_layered_walk("list", wsp) == -1) {
-		mdb_warn("failed to walk session list");
-		return (WALK_ERR);
-	}
+/*
+ * MDB module linkage information:
+ *
+ * We declare a list of structures describing our dcmds, a list of structures
+ * describing our walkers and a function named _mdb_init to return a pointer
+ * to our module information.
+ */
+static const mdb_dcmd_t dcmds[] = {
+	{   "smblist",
+	    "[-seutfdwv]",
+	    "print tree of SMB objects",
+	    smb_dcmd_list,
+	    smb_dcmd_list_help },
+	{   "smbsrv",
+	    "[-seutfdwv]",
+	    "print smb_server information",
+	    smb_dcmd_server },
+	{   "smbvfs",
+	    "[-v]",
+	    "print smb_vfs information",
+	    smb_dcmd_vfs },
+	{   "smbnode",
+	    "?[-vps]",
+	    "print smb_node_t information",
+	    smb_node,
+	    smb_node_help },
+	{   "smbsess",
+	    "[-utfdwv]",
+	    "print smb_session_t information",
+	    smb_dcmd_session,
+	    smb_dcmd_session_help},
+	{   "smbreq",
+	    ":[-v]",
+	    "print smb_request_t information",
+	    smb_dcmd_request },
+	{   "smblock", ":[-v]",
+	    "print smb_lock_t information", smb_lock },
+	{   "smbuser",
+	    ":[-vdftq]",
+	    "print smb_user_t information",
+	    smb_dcmd_user,
+	    smb_dcmd_user_help },
+	{   "smbtree",
+	    ":[-vdf]",
+	    "print smb_tree_t information",
+	    smb_dcmd_tree,
+	    smb_dcmd_tree_help },
+	{   "smbodir",
+	    ":[-v]",
+	    "print smb_odir_t information",
+	    smb_dcmd_odir },
+	{   "smbofile",
+	    "[-v]",
+	    "print smb_odir_t information",
+	    smb_dcmd_ofile },
+	{   "smbstats", NULL,
+	    "print all smb dispatched requests statistics", smb_stats },
+	{   "smbace", "[-v]",
+	    "print smb_ace_t information", smb_ace },
+	{   "smbacl", "[-v]",
+	    "print smb_acl_t information", smb_acl },
+	{   "smbsid", "[-v]",
+	    "print smb_sid_t information", smb_sid },
+	{   "smbsd", "[-v]",
+	    "print smb_sd_t information", smb_sd },
+	{   "smbfssd", "[-v]",
+	    "print smb_fssd_t information", smb_fssd },
+	{ NULL }
+};
 
-	return (WALK_NEXT);
-}
+static const mdb_walker_t walkers[] = {
+	{   "smbnode_walker",
+	    "walk list of smb_node_t structures",
+	    smb_node_walk_init,
+	    smb_node_walk_step,
+	    NULL,
+	    NULL },
+	{   "smbace_walker",
+	    "walk list of smb_ace_t structures",
+	    smb_ace_walk_init,
+	    smb_ace_walk_step,
+	    NULL,
+	    NULL },
+	{ NULL }
+};
 
-static int
-smb_session_walk_step(mdb_walk_state_t *wsp)
+static const mdb_modinfo_t modinfo = {
+	MDB_API_VERSION, dcmds, walkers
+};
+
+const mdb_modinfo_t *
+_mdb_init(void)
 {
-	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
-	    wsp->walk_cbdata));
+	return (&modinfo);
 }
 
 /*
- * Initialize the smb_node_t walker by reading the value of smb_info
- * object in the kernel's symbol table. Only global walk supported.
+ * *****************************************************************************
+ * ****************************** Top level DCMD *******************************
+ * *****************************************************************************
  */
+
+static void
+smb_dcmd_list_help(void)
+{
+	mdb_printf(
+	    "Displays the list of objects using an indented tree format.\n"
+	    "If no option is specified the entire tree is displayed\n\n");
+	(void) mdb_dec_indent(2);
+	mdb_printf("%<b>OPTIONS%</b>\n");
+	(void) mdb_inc_indent(2);
+	mdb_printf(
+	    "-v\tDisplay verbose information\n"
+	    "-s\tDisplay the list of servers\n"
+	    "-m\tDisplay the list of shared file systems\n"
+	    "-e\tDisplay the list of sessions\n"
+	    "-r\tDisplay the list of smb requests\n"
+	    "-u\tDisplay the list of users\n"
+	    "-t\tDisplay the list of trees\n"
+	    "-f\tDisplay the list of open files\n"
+	    "-d\tDisplay the list of open searches\n");
+}
+
+/*
+ * ::smblist
+ *
+ * This function lists the objects specified on the command line. If no object
+ * is specified the entire tree (server through ofile and odir) is displayed.
+ *
+ */
+/*ARGSUSED*/
 static int
-smb_node_walk_init(mdb_walk_state_t *wsp)
+smb_dcmd_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 {
 	GElf_Sym	sym;
-	int		i;
-	uintptr_t	node_hash_table_addr;
+	uint_t		opts = 0;
+	int		new_argc;
+	mdb_arg_t	new_argv[SMB_MDB_MAX_OPTS];
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(opts & ~(SMB_OPT_WALK | SMB_OPT_VERBOSE)))
+		opts |= SMB_OPT_ALL_OBJ;
+
+	opts |= SMB_OPT_WALK;
+
+	new_argc = smb_dcmd_setopt(opts, SMB_MDB_MAX_OPTS, new_argv);
+
+	if (mdb_lookup_by_name("smb_servers", &sym) == -1) {
+		mdb_warn("failed to find symbol smb_servers");
+		return (DCMD_ERR);
+	}
+
+	addr = (uintptr_t)sym.st_value + offsetof(smb_llist_t, ll_list);
+
+	if (mdb_pwalk_dcmd("list", "smbsrv", new_argc, new_argv, addr))
+		return (DCMD_ERR);
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ***************************** smb_server_t **********************************
+ * *****************************************************************************
+ */
+
+static const char *smb_server_state[SMB_SERVER_STATE_SENTINEL] =
+{
+	"CREATED",
+	"CONFIGURED",
+	"RUNNING",
+	"DELETING"
+};
+
+/*
+ * List of objects that can be expanded under a server structure.
+ */
+static const smb_exp_t smb_server_exp[] =
+{
+	{ SMB_OPT_ALL_OBJ,
+	    offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_rdy.lst),
+	    "smbsess", "smb_session"},
+	{ SMB_OPT_ALL_OBJ,
+	    offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_act.lst),
+	    "smbsess", "smb_session"},
+	{ SMB_OPT_ALL_OBJ,
+	    offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_rdy.lst),
+	    "smbsess", "smb_session"},
+	{ SMB_OPT_ALL_OBJ,
+	    offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_act.lst),
+	    "smbsess", "smb_session"},
+	{ SMB_OPT_ALL_OBJ,
+	    offsetof(smb_server_t, sv_vfs_list.ll_list),
+	    "smbvfs", "smb_vfs"},
+	{ 0, 0, NULL, NULL }
+};
+
+/*
+ * ::smbsrv
+ *
+ * smbsrv dcmd - Print out smb_server structures.
+ */
+/*ARGSUSED*/
+static int
+smb_dcmd_server(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	uint_t		opts;
+	ulong_t		indent = 0;
 
-	if (wsp->walk_addr == NULL) {
-		if (mdb_lookup_by_name("smb_node_hash_table", &sym) == -1) {
-			mdb_warn("failed to find 'smb_node_hash_table'");
-			return (WALK_ERR);
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(flags & DCMD_ADDRSPEC))
+		return (smb_obj_list("smb_server", opts | SMB_OPT_SERVER,
+		    flags));
+
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SERVER)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_server_t	*sv;
+		const char	*state;
+
+		sv = mdb_alloc(sizeof (smb_server_t), UM_SLEEP | UM_GC);
+		if (mdb_vread(sv, sizeof (smb_server_t), addr) == -1) {
+			mdb_warn("failed to read smb_server at %p", addr);
+			return (DCMD_ERR);
 		}
-		node_hash_table_addr = (uintptr_t)sym.st_value;
-	} else {
-		mdb_printf("smb_node walk only supports global walks\n");
-		return (WALK_ERR);
+
+		indent = SMB_DCMD_INDENT;
+
+		if (opts & SMB_OPT_VERBOSE) {
+			mdb_arg_t	argv;
+
+			argv.a_type = MDB_TYPE_STRING;
+			argv.a_un.a_str = "smb_server_t";
+			if (mdb_call_dcmd("print", addr, flags, 1, &argv))
+				return (DCMD_ERR);
+		} else {
+			if (DCMD_HDRSPEC(flags))
+				mdb_printf(
+				    "%<b>%<u>%-?s% "
+				    "%-4s% "
+				    "%-32s% "
+				    "%-6s% "
+				    "%-6s% "
+				    "%-6s%</u>%</b>\n",
+				    "SERVER", "ZONE", "STATE", "USERS",
+				    "TREES", "FILES");
+
+			if (sv->sv_state >= SMB_SERVER_STATE_SENTINEL)
+				state = "UNKNOWN";
+			else
+				state = smb_server_state[sv->sv_state];
+
+			mdb_printf("%-?p %-4d %-32s %-6d %-6d %-6d \n",
+			    addr, sv->sv_zid, state, sv->sv_open_users,
+			    sv->sv_open_trees, sv->sv_open_files);
+		}
+	}
+	if (smb_obj_expand(addr, opts, smb_server_exp, indent))
+		return (DCMD_ERR);
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ******************************** smb_vfs_t **********************************
+ * *****************************************************************************
+ */
+
+/*
+ * ::smbvfs
+ *
+ * smbvfs dcmd - Prints out smb_vfs structures.
+ */
+/*ARGSUSED*/
+static int
+smb_dcmd_vfs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+
+	uint_t		opts;
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		return (smb_obj_list("smb_vfs", SMB_OPT_VFS, flags));
 	}
 
-	for (i = 0; i < SMBND_HASH_MASK + 1; i++) {
-		wsp->walk_addr = node_hash_table_addr +
-		    (i * sizeof (smb_llist_t)) +
-		    offsetof(smb_llist_t, ll_list);
-		if (mdb_layered_walk("list", wsp) == -1) {
-			mdb_warn("failed to walk 'list'");
-			return (WALK_ERR);
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_VFS)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_vfs_t	*sf;
+		vnode_t		*vn;
+		char		*path;
+
+		sf = mdb_alloc(sizeof (*sf), UM_SLEEP | UM_GC);
+		if (mdb_vread(sf, sizeof (*sf), addr) == -1) {
+			mdb_warn("failed to read smb_vfs at %p", addr);
+			return (DCMD_ERR);
+		}
+		vn = mdb_alloc(sizeof (*vn), UM_SLEEP | UM_GC);
+		if (mdb_vread(vn, sizeof (*vn),
+		    (uintptr_t)sf->sv_rootvp) == -1) {
+			mdb_warn("failed to read vnode at %p", sf->sv_rootvp);
+			return (DCMD_ERR);
+		}
+		path = mdb_zalloc(MAXPATHLEN, UM_SLEEP | UM_GC);
+		(void) mdb_vread(path, MAXPATHLEN, (uintptr_t)vn->v_path);
+
+		if (DCMD_HDRSPEC(flags))
+			mdb_printf(
+			    "%<b>%<u>"
+			    "%-?s "
+			    "%-10s "
+			    "%-16s "
+			    "%-16s"
+			    "%-s"
+			    "%</u>%</b>\n",
+			    "SMB_VFS", "REFCNT", "VFS", "VNODE", "ROOT");
+		mdb_printf(
+		    "%-?p %-10d %-?p %-?p %-s\n", addr, sf->sv_refcnt,
+		    sf->sv_vfsp, sf->sv_rootvp, path);
+	}
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ***************************** smb_session_t *********************************
+ * *****************************************************************************
+ */
+
+static const char *smb_session_state[SMB_SESSION_STATE_SENTINEL] =
+{
+	"INITIALIZED",
+	"DISCONNECTED",
+	"CONNECTED",
+	"ESTABLISHED",
+	"NEGOTIATED",
+	"OPLOCK_BREAKING",
+	"WRITE_RAW_ACTIVE",
+	"TERMINATED"
+};
+
+/*
+ * List of objects that can be expanded under a session structure.
+ */
+static const smb_exp_t smb_session_exp[] =
+{
+	{ SMB_OPT_REQUEST,
+	    offsetof(smb_session_t, s_req_list.sl_list),
+	    "smbreq", "smb_request"},
+	{ SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_OFILE | SMB_OPT_ODIR,
+	    offsetof(smb_session_t, s_user_list.ll_list),
+	    "smbuser", "smb_user"},
+	{ 0, 0, NULL, NULL}
+};
+
+static void
+smb_dcmd_session_help(void)
+{
+	mdb_printf(
+	    "Display the contents of smb_session_t, with optional"
+	    " filtering.\n\n");
+	(void) mdb_dec_indent(2);
+	mdb_printf("%<b>OPTIONS%</b>\n");
+	(void) mdb_inc_indent(2);
+	mdb_printf(
+	    "-v\tDisplay verbose smb_session information\n"
+	    "-r\tDisplay the list of smb requests attached\n"
+	    "-u\tDisplay the list of users attached\n");
+}
+
+/*
+ * ::smbsess
+ *
+ * smbsess dcmd - Print out the smb_session structure.
+ */
+/*ARGSUSED*/
+static int
+smb_dcmd_session(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	uint_t		opts;
+	ulong_t		indent = 0;
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		opts |= SMB_OPT_SESSION;
+		opts &= ~SMB_OPT_SERVER;
+		return (smb_obj_list("smb_session", opts, flags));
+	}
+
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SESSION)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_session_t	*se;
+		const char	*state;
+
+		indent = SMB_DCMD_INDENT;
+
+		se = mdb_alloc(sizeof (*se), UM_SLEEP | UM_GC);
+		if (mdb_vread(se, sizeof (*se), addr) == -1) {
+			mdb_warn("failed to read smb_session at %p", addr);
+			return (DCMD_ERR);
+		}
+
+		if (se->s_state >= SMB_SESSION_STATE_SENTINEL)
+			state = "INVALID";
+		else
+			state = smb_session_state[se->s_state];
+
+		if (opts & SMB_OPT_VERBOSE) {
+			mdb_printf("%<b>%<u>SMB session information "
+			    "(%p): %</u>%</b>\n", addr);
+			mdb_printf("Client IP address: %I\n", se->ipaddr);
+			mdb_printf("Local IP Address: %I\n", se->local_ipaddr);
+			mdb_printf("Session KID: %u\n", se->s_kid);
+			mdb_printf("Workstation Name: %s\n",
+			    se->workstation);
+			mdb_printf("Session state: %u (%s)\n", se->s_state,
+			    state);
+			mdb_printf("Number of Users: %u\n",
+			    se->s_user_list.ll_count);
+			mdb_printf("Number of Trees: %u\n", se->s_tree_cnt);
+			mdb_printf("Number of Files: %u\n", se->s_file_cnt);
+			mdb_printf("Number of Shares: %u\n", se->s_dir_cnt);
+			mdb_printf("Number of active Transact.: %u\n\n",
+			    se->s_xa_list.ll_count);
+		} else {
+			if (DCMD_HDRSPEC(flags))
+				mdb_printf(
+				    "%<b>%<u>%-?s "
+				    "%-16s "
+				    "%-16s%</u>\n",
+				    "SESSION", "CLIENT_IP_ADDR",
+				    "LOCAL_IP_ADDR");
+			mdb_printf(
+			    "%-?p %-16I %-16I\n", addr, se->ipaddr,
+			    se->local_ipaddr);
 		}
 	}
+	if (smb_obj_expand(addr, opts, smb_session_exp, indent))
+		return (DCMD_ERR);
+	return (DCMD_OK);
+}
 
-	return (WALK_NEXT);
+/*
+ * *****************************************************************************
+ * **************************** smb_request_t **********************************
+ * *****************************************************************************
+ */
+
+static const char *smb_request_state[SMB_REQ_STATE_SENTINEL] =
+{
+	"FREE",
+	"INITIALIZING",
+	"SUBMITTED",
+	"ACTIVE",
+	"WAITING_EVENT",
+	"EVENT_OCCURRED",
+	"WAITING_LOCK",
+	"COMPLETED",
+	"CANCELED",
+	"CLEANED_UP"
+};
+
+static int
+smb_dcmd_request(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	uint_t		opts;
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		opts |= SMB_OPT_REQUEST;
+		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_USER);
+		return (smb_obj_list("smb_request", opts, flags));
+	}
+
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_REQUEST)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_request_t	*sr;
+		const char	*state;
+
+		sr = mdb_alloc(sizeof (*sr), UM_SLEEP | UM_GC);
+		if (mdb_vread(sr, sizeof (*sr), addr) == -1) {
+			mdb_warn("failed to read smb_request at %p", addr);
+			return (DCMD_ERR);
+		}
+
+		if (sr->sr_state >= SMB_REQ_STATE_SENTINEL)
+			state = "INVALID";
+		else
+			state = smb_request_state[sr->sr_state];
+
+		if (opts & SMB_OPT_VERBOSE) {
+			mdb_printf(
+			    "%<b>%<u>SMB request information (%p):"
+			    "%</u>%</b>\n\n", addr);
+			mdb_printf("First SMB COM: %u (%s)\n",
+			    sr->first_smb_com,
+			    smb_com[sr->first_smb_com]);
+			mdb_printf("State: %u (%s)\n", sr->sr_state, state);
+			mdb_printf("Tree: %u (%p)\n", sr->smb_tid,
+			    sr->tid_tree);
+			mdb_printf("User: %u (%p)\n", sr->smb_uid,
+			    sr->uid_user);
+			mdb_printf("File: %u (%p)\n",
+			    sr->smb_fid, sr->fid_ofile);
+			mdb_printf("Dir.: %u (%p)\n", sr->smb_sid,
+			    sr->sid_odir);
+			mdb_printf("PID: %u\n", sr->smb_pid);
+			mdb_printf("MID: %u\n\n", sr->smb_mid);
+		} else {
+			if (DCMD_HDRSPEC(flags))
+				mdb_printf(
+				    "%<b>%<u>"
+				    "%-?s "
+				    "%s%</u>%</b>\n"
+				    "ADDR", "COM");
+
+			mdb_printf("%-?p %s\n", addr, state,
+			    smb_com[sr->first_smb_com]);
+		}
+	}
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ****************************** smb_user_t ***********************************
+ * *****************************************************************************
+ */
+
+static const char *smb_user_state[SMB_USER_STATE_SENTINEL] =
+{
+	"LOGGED_IN",
+	"LOGGING_OFF",
+	"LOGGED_OFF"
+};
+
+/*
+ * List of objects that can be expanded under a user structure.
+ */
+static const smb_exp_t smb_user_exp[] =
+{
+	{ SMB_OPT_TREE | SMB_OPT_OFILE | SMB_OPT_ODIR,
+	    offsetof(smb_user_t, u_tree_list.ll_list),
+	    "smbtree", "smb_tree"},
+	{ 0, 0, NULL, NULL}
+};
+
+static void
+smb_dcmd_user_help(void)
+{
+	mdb_printf(
+	    "Display the contents of smb_user_t, with optional filtering.\n\n");
+	(void) mdb_dec_indent(2);
+	mdb_printf("%<b>OPTIONS%</b>\n");
+	(void) mdb_inc_indent(2);
+	mdb_printf(
+	    "-v\tDisplay verbose smb_user information\n"
+	    "-d\tDisplay the list of smb_odirs attached\n"
+	    "-f\tDisplay the list of smb_ofiles attached\n"
+	    "-t\tDisplay the list of smb_trees attached\n");
 }
 
 static int
-smb_node_walk_step(mdb_walk_state_t *wsp)
+smb_dcmd_user(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 {
-	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
-	    wsp->walk_cbdata));
+	uint_t		opts;
+	ulong_t		indent = 0;
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		opts |= SMB_OPT_USER;
+		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST);
+		return (smb_obj_list("smb_user", opts, flags));
+	}
+
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_USER)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_user_t	*user;
+		char		*account;
+
+		indent = SMB_DCMD_INDENT;
+
+		user = mdb_alloc(sizeof (*user), UM_SLEEP | UM_GC);
+		if (mdb_vread(user, sizeof (*user), addr) == -1) {
+			mdb_warn("failed to read smb_user at %p", addr);
+			return (DCMD_ERR);
+		}
+
+		account = mdb_zalloc(user->u_domain_len + user->u_name_len + 2,
+		    UM_SLEEP | UM_GC);
+
+		if (user->u_domain_len)
+			(void) mdb_vread(account, user->u_domain_len,
+			    (uintptr_t)user->u_domain);
+
+		strcat(account, "\\");
+
+		if (user->u_name_len)
+			(void) mdb_vread(account + strlen(account),
+			    user->u_name_len, (uintptr_t)user->u_name);
+
+		if (opts & SMB_OPT_VERBOSE) {
+			const char	*state;
+
+			if (user->u_state >= SMB_USER_STATE_SENTINEL)
+				state = "INVALID";
+			else
+				state = smb_user_state[user->u_state];
+
+			mdb_printf("%<b>%<u>SMB user information (%p):"
+			    "%</u>%</b>\n", addr);
+			mdb_printf("UID: %u\n", user->u_uid);
+			mdb_printf("State: %d (%s)\n", user->u_state, state);
+			mdb_printf("Flags: 0x%08x\n", user->u_flags);
+			mdb_printf("Privileges: 0x%08x\n", user->u_privileges);
+			mdb_printf("Credential: %p\n", user->u_cred);
+			mdb_printf("Reference Count: %d\n", user->u_refcnt);
+			mdb_printf("User Account: %s\n\n", account);
+		} else {
+			if (DCMD_HDRSPEC(flags))
+				mdb_printf(
+				    "%<b>%<u>%?-s "
+				    "%-5s "
+				    "%-32s%</u>%</b>\n",
+				    "USER", "UID", "ACCOUNT");
+
+			mdb_printf("%-?p %-5u %-32s\n", addr, user->u_uid,
+			    account);
+		}
+	}
+	if (smb_obj_expand(addr, opts, smb_user_exp, indent))
+		return (DCMD_ERR);
+	return (DCMD_OK);
 }
 
 /*
- * ::smb_info
- *
- * smb_info dcmd - Print out the smb_info structure.
+ * *****************************************************************************
+ * ****************************** smb_tree_t ***********************************
+ * *****************************************************************************
  */
-/*ARGSUSED*/
-static int
-smb_information(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+
+static const char *smb_tree_state[SMB_TREE_STATE_SENTINEL] =
+{
+	"CONNECTED",
+	"DISCONNECTING",
+	"DISCONNECTED"
+};
+
+/*
+ * List of objects that can be expanded under a tree structure.
+ */
+static const smb_exp_t smb_tree_exp[] =
 {
-	int		print_config = FALSE;
-	uintptr_t	sv_addr;
-	smb_server_t	*sv;
-	GElf_Sym	smb_server_sym;
-	char		state_name[40];
+	{ SMB_OPT_OFILE,
+	    offsetof(smb_tree_t, t_ofile_list.ll_list),
+	    "smbofile", "smb_ofile"},
+	{ SMB_OPT_ODIR,
+	    offsetof(smb_tree_t, t_odir_list.ll_list),
+	    "smbodir", "smb_odir"},
+	{ 0, 0, NULL, NULL}
+};
 
-	if (mdb_getopts(argc, argv,
-	    'c', MDB_OPT_SETBITS, TRUE, &print_config,
-	    NULL) != argc)
+static void
+smb_dcmd_tree_help(void)
+{
+	mdb_printf(
+	    "Display the contents of smb_tree_t, with optional filtering.\n\n");
+	(void) mdb_dec_indent(2);
+	mdb_printf("%<b>OPTIONS%</b>\n");
+	(void) mdb_inc_indent(2);
+	mdb_printf(
+	    "-v\tDisplay verbose smb_tree information\n"
+	    "-d\tDisplay the list of smb_odirs attached\n"
+	    "-f\tDisplay the list of smb_ofiles attached\n");
+}
+
+static int
+smb_dcmd_tree(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	uint_t		opts;
+	ulong_t		indent = 0;
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
 		return (DCMD_USAGE);
 
-	if (flags & DCMD_ADDRSPEC)
-		return (DCMD_USAGE);
-
-	if (mdb_lookup_by_obj(MDB_OBJ_EVERY, "smb_server", &smb_server_sym)) {
-		mdb_warn("failed to find symbol smb_server");
-		return (DCMD_ERR);
-	}
-
-	if (mdb_readvar(&sv_addr, "smb_server") == -1) {
-		mdb_warn("failed to read smb_server address");
-		return (DCMD_ERR);
-	}
-	if (sv_addr == 0) {
-		mdb_printf("No SMB Server exits yet\n");
-		return (DCMD_OK);
+	if (!(flags & DCMD_ADDRSPEC)) {
+		opts |= SMB_OPT_TREE;
+		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
+		    SMB_OPT_USER);
+		return (smb_obj_list("smb_tree", opts, flags));
 	}
 
-	sv = mdb_alloc(sizeof (smb_server_t), UM_SLEEP);
-	if (mdb_vread(sv, sizeof (smb_server_t), sv_addr) == -1) {
-		mdb_free(sv, sizeof (smb_server_t));
-		mdb_warn("failed to read smb_server contents");
-		return (DCMD_ERR);
-	}
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_TREE)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_tree_t	*tree;
+
+		indent = SMB_DCMD_INDENT;
 
-	smb_server_lookup_state_str(sv->sv_state, state_name,
-	    sizeof (state_name));
+		tree = mdb_alloc(sizeof (*tree), UM_SLEEP | UM_GC);
+		if (mdb_vread(tree, sizeof (*tree), addr) == -1) {
+			mdb_warn("failed to read smb_tree at %p", addr);
+			return (DCMD_ERR);
+		}
 
-	mdb_printf("SMB Server:\n\n");
-	mdb_printf("        SMB state :\t%s (%d)\n", state_name, sv->sv_state);
-	mdb_printf("  Active Sessions :\t%d\n",
-	    sv->sv_nbt_daemon.ld_session_list.se_act.count +
-	    sv->sv_tcp_daemon.ld_session_list.se_act.count);
-	mdb_printf("   SMB Open Files :\t%d\n", sv->sv_open_files);
-	mdb_printf("   SMB Open Trees :\t%d\n", sv->sv_open_trees);
-	mdb_printf("   SMB Open Users :\t%d\n\n", sv->sv_open_users);
+		if (opts & SMB_OPT_VERBOSE) {
+			const char	*state;
+
+			if (tree->t_state >= SMB_TREE_STATE_SENTINEL)
+				state = "INVALID";
+			else
+				state = smb_tree_state[tree->t_state];
 
-	if (print_config) {
-		mdb_printf("Configuration:\n\n");
-		(void) mdb_inc_indent(SMB_DCMD_INDENT);
-		mdb_printf("Max Worker Thread %d\n",
-		    sv->sv_cfg.skc_maxworkers);
-		mdb_printf("Max Connections %d\n",
-		    sv->sv_cfg.skc_maxconnections);
-		mdb_printf("Keep Alive Timeout %d\n",
-		    sv->sv_cfg.skc_keepalive);
-		mdb_printf("%sRestrict Anonymous Access\n",
-		    (sv->sv_cfg.skc_restrict_anon) ? "" : "Do Not ");
-		mdb_printf("Signing %s\n",
-		    (sv->sv_cfg.skc_signing_enable) ? "Enabled" : "Disabled");
-		mdb_printf("Signing %sRequired\n",
-		    (sv->sv_cfg.skc_signing_required) ? "" : "Not ");
-		mdb_printf("Signing Check %s\n",
-		    (sv->sv_cfg.skc_signing_check) ? "Enabled" : "Disabled");
-		mdb_printf("Oplocks %s\n",
-		    (sv->sv_cfg.skc_oplock_enable) ? "Enabled" : "Disabled");
-		mdb_printf("Sync %s\n",
-		    (sv->sv_cfg.skc_sync_enable) ? "Enabled" : "Disabled");
-		mdb_printf("Security Mode %d\n", sv->sv_cfg.skc_secmode);
-		mdb_printf("Domain %s\n", sv->sv_cfg.skc_resource_domain);
-		mdb_printf("Hostname %s\n", sv->sv_cfg.skc_hostname);
-		mdb_printf("Comment %s\n", sv->sv_cfg.skc_system_comment);
-		(void) mdb_dec_indent(SMB_DCMD_INDENT);
-		mdb_printf("\n");
+			mdb_printf("%<b>%<u>SMB tree information (%p):"
+			    "%</u>%</b>\n\n", addr);
+			mdb_printf("TID: %04x\n", tree->t_tid);
+			mdb_printf("State: %d (%s)\n", tree->t_state, state);
+			mdb_printf("Share name: %s\n", tree->t_sharename);
+			mdb_printf("Resource: %s\n", tree->t_resource);
+			mdb_printf("Umask: %04x\n", tree->t_umask);
+			mdb_printf("Access: %04x\n", tree->t_access);
+			mdb_printf("Flags: %08x\n", tree->t_flags);
+			mdb_printf("SMB Node: %llx\n", tree->t_snode);
+			mdb_printf("Reference Count: %d\n\n", tree->t_refcnt);
+		} else {
+			if (DCMD_HDRSPEC(flags))
+				mdb_printf(
+				    "%<b>%<u>%-?s %-5s %-16s %-32s%</u>%</b>\n",
+				    "TREE", "TID", "SHARE NAME", "RESOURCE");
+
+			mdb_printf("%-?p %-5u %-16s %-32s\n", addr,
+			    tree->t_tid, tree->t_sharename, tree->t_resource);
+		}
 	}
-
+	if (smb_obj_expand(addr, opts, smb_tree_exp, indent))
+		return (DCMD_ERR);
 	return (DCMD_OK);
 }
 
-static void
-smb_server_lookup_state_str(smb_server_state_t state, char *dst_str, int slen)
+/*
+ * *****************************************************************************
+ * ****************************** smb_odir_t ***********************************
+ * *****************************************************************************
+ */
+
+static const char *smb_odir_state[SMB_ODIR_STATE_SENTINEL] =
 {
-	GElf_Sym	smb_statename_table_sym;
-	uintptr_t	statename_addr_addr, statename_addr;
+	"OPEN",
+	"CLOSING",
+	"CLOSED"
+};
 
-	if (mdb_lookup_by_name("smb_server_state_name",
-	    &smb_statename_table_sym)) {
-		(void) mdb_snprintf(dst_str, slen, "UNKNOWN");
-		return;
+static int
+smb_dcmd_odir(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	uint_t		opts;
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		opts |= SMB_OPT_ODIR;
+		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
+		    SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_OFILE);
+		return (smb_obj_list("smb_odir", opts, flags));
 	}
 
-	/* Lookup state string */
-	statename_addr_addr = smb_statename_table_sym.st_value +
-	    (state * sizeof (uintptr_t));
-	if (mdb_vread(&statename_addr, sizeof (uintptr_t),
-	    statename_addr_addr) == -1) {
-		(void) mdb_snprintf(dst_str, slen, "UNKNOWN");
-		return;
-	} else {
-		if (mdb_readstr(dst_str, slen, statename_addr) == -1) {
-			(void) mdb_snprintf(dst_str, slen, "UNKNOWN");
-			return;
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_ODIR)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_odir_t	*od;
+
+		od = mdb_alloc(sizeof (*od), UM_SLEEP | UM_GC);
+		if (mdb_vread(od, sizeof (*od), addr) == -1) {
+			mdb_warn("failed to read smb_odir at %p", addr);
+			return (DCMD_ERR);
+		}
+
+		if (opts & SMB_OPT_VERBOSE) {
+			const char	*state;
+
+			if (od->d_state >= SMB_ODIR_STATE_SENTINEL)
+				state = "INVALID";
+			else
+				state = smb_odir_state[od->d_state];
+
+			mdb_printf(
+			    "%<b>%<u>SMB odir information (%p):%</u>%</b>\n\n",
+			    addr);
+			mdb_printf("State: %d (%s)\n", od->d_state, state);
+			mdb_printf("SID: %u\n", od->d_sid);
+			mdb_printf("Reference Count: %d\n", od->d_refcnt);
+			mdb_printf("Pattern: %s\n", od->d_pattern);
+			mdb_printf("SMB Node: %p\n\n", od->d_dir_snode);
+		} else {
+			if (DCMD_HDRSPEC(flags))
+				mdb_printf(
+				    "%<u>%-?s "
+				    "%-5s "
+				    "%-?s "
+				    "%-16s%</u>\n",
+				    "ODIR", "SID", "VNODE", "PATTERN");
+
+			mdb_printf("%?p %-5u %-16s %s\n",
+			    addr, od->d_sid, od->d_dir_snode, od->d_pattern);
 		}
 	}
+	return (DCMD_OK);
 }
 
+/*
+ * *****************************************************************************
+ * ****************************** smb_ofile_t **********************************
+ * *****************************************************************************
+ */
+
+static const char *smb_ofile_state[SMB_OFILE_STATE_SENTINEL] =
+{
+	"OPEN",
+	"CLOSING",
+	"CLOSED"
+};
+
+static int
+smb_dcmd_ofile(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	uint_t		opts;
+
+	if (smb_dcmd_getopt(&opts, argc, argv))
+		return (DCMD_USAGE);
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		opts |= SMB_OPT_OFILE;
+		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
+		    SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_ODIR);
+		return (smb_obj_list("smb_ofile", opts, flags));
+	}
+
+	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_OFILE)) ||
+	    !(opts & SMB_OPT_WALK)) {
+		smb_ofile_t	*of;
+
+		of = mdb_alloc(sizeof (*of), UM_SLEEP | UM_GC);
+		if (mdb_vread(of, sizeof (*of), addr) == -1) {
+			mdb_warn("failed to read smb_ofile at %p", addr);
+			return (DCMD_ERR);
+		}
+
+		if (opts & SMB_OPT_VERBOSE) {
+			const char	*state;
+
+			if (of->f_state >= SMB_ODIR_STATE_SENTINEL)
+				state = "INVALID";
+			else
+				state = smb_ofile_state[of->f_state];
+
+			mdb_printf(
+			    "%<b>%<u>SMB ofile information (%p):%</u>%</b>\n\n",
+			    addr);
+			mdb_printf("FID: %u\n", of->f_fid);
+			mdb_printf("State: %d (%s)\n", of->f_state, state);
+			mdb_printf("SMB Node: %p\n", of->f_node);
+			mdb_printf("LLF Offset: 0x%llx (%s)\n",
+			    of->f_llf_pos,
+			    ((of->f_flags & SMB_OFLAGS_LLF_POS_VALID) ?
+			    "Valid" : "Invalid"));
+			mdb_printf("Flags: 0x%08x\n", of->f_flags);
+			mdb_printf("Credential: %p\n\n", of->f_cr);
+		} else {
+			if (DCMD_HDRSPEC(flags))
+				mdb_printf(
+				    "%<b>%<u>%-?s "
+				    "%-5s "
+				    "%-?s "
+				    "%-?s%</u>%</b>\n",
+				    "OFILE", "FID", "SMB NODE", "CRED");
+
+			mdb_printf("%?p %-5u %-p %p\n", addr,
+			    of->f_fid, of->f_node, of->f_cr);
+		}
+	}
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ******************************* smb_node_t **********************************
+ * *****************************************************************************
+ */
+
 static void
 smb_node_help(void)
 {
 	mdb_printf(
 	    "Display the contents of smb_node_t, with optional filtering.\n\n");
-	mdb_dec_indent(2);
+	(void) mdb_dec_indent(2);
 	mdb_printf("%<b>OPTIONS%</b>\n");
-	mdb_inc_indent(2);
+	(void) mdb_inc_indent(2);
 	mdb_printf(
 	    "-v\tDisplay verbose smb_node information\n"
 	    "-p\tDisplay the full path of the vnode associated\n"
@@ -276,11 +1287,10 @@
 }
 
 /*
- * ::smb_node
+ * ::smbnode
  *
  * smb_node dcmd - Print out smb_node structure.
  */
-/*ARGSUSED*/
 static int
 smb_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 {
@@ -306,7 +1316,7 @@
 	 * this dcmd itself as the callback.
 	 */
 	if (!(flags & DCMD_ADDRSPEC)) {
-		if (mdb_walk_dcmd("smb_node", "smb_node",
+		if (mdb_walk_dcmd("smbnode_walker", "smbnode",
 		    argc, argv) == -1) {
 			mdb_warn("failed to walk 'smb_node'");
 			return (DCMD_ERR);
@@ -319,85 +1329,75 @@
 	 * header line for the output that will follow.
 	 */
 	if (DCMD_HDRSPEC(flags)) {
-		if (verbose)
-			mdb_printf("SMB node information:\n\n");
-		else
-			mdb_printf("%<u>%?s %?s %18s %6s %5s %4s%</u>\n",
-			    "SMB Nodes:", "VP", "NODE NAME",
-			    "OFILES", "LOCKS", "REF");
+		if (verbose) {
+			mdb_printf("%<b>%<u>SMB node information:%</u>%</b>\n");
+		} else {
+			mdb_printf(
+			    "%<b>%<u>%-?s "
+			    "%-?s "
+			    "%-18s "
+			    "%-6s "
+			    "%-6s "
+			    "%-6s%</u>%</b>\n",
+			    "ADDR", "VP", "NODE-NAME", "OFILES", "LOCKS",
+			    "REF");
+		}
 	}
 
 	/*
-	 * For each smb_node, we just need to read the smb_node_t struct,
-	 * read and then print out the following fields.
+	 * For each smb_node, we just need to read the smb_node_t struct, read
+	 * and then print out the following fields.
 	 */
 	if (mdb_vread(&node, sizeof (node), addr) == sizeof (node)) {
-		(void) mdb_snprintf(od_name, MAXNAMELEN, "%s", node.od_name);
+		(void) mdb_snprintf(od_name, sizeof (od_name), "%s",
+		    node.od_name);
 		if (print_full_path) {
 			if (mdb_vread(&vnode, sizeof (vnode_t),
-			    (uintptr_t)node.vp) ==
-			    sizeof (vnode_t)) {
-				if (mdb_readstr(path_name, 1024,
+			    (uintptr_t)node.vp) == sizeof (vnode_t)) {
+				if (mdb_readstr(path_name, sizeof (path_name),
 				    (uintptr_t)vnode.v_path) != 0) {
 					(void) mdb_snprintf(od_name,
-					    MAXNAMELEN, "N/A");
+					    sizeof (od_name), "N/A");
 				}
 			}
 		}
 		if (verbose) {
-			mdb_printf("VP              :\t%p\n",
-			    node.vp);
-			mdb_printf("Name            :\t%s\n",
-			    od_name);
-			if (print_full_path) {
-				mdb_printf("V-node Path     :\t%s\n",
-				    path_name);
-			}
-			mdb_printf("Ofiles          :\t%u\n",
-			    node.n_ofile_list.ll_count);
-			mdb_printf("Range Locks     :\t%u\n",
+			mdb_printf("VP: %p\n", node.vp);
+			mdb_printf("Name: %s\n", od_name);
+			if (print_full_path)
+				mdb_printf("V-node Path: %s\n", path_name);
+			mdb_printf("Ofiles: %u\n", node.n_ofile_list.ll_count);
+			mdb_printf("Range Locks: %u\n",
 			    node.n_lock_list.ll_count);
 			if (node.n_lock_list.ll_count != 0) {
 				(void) mdb_inc_indent(SMB_DCMD_INDENT);
 				list_addr = addr +
 				    offsetof(smb_node_t, n_lock_list) +
 				    offsetof(smb_llist_t, ll_list);
-				if (mdb_pwalk_dcmd("list", "smb_lock",
-				    0, NULL, list_addr)) {
+				if (mdb_pwalk_dcmd("list", "smblock", 0,
+				    NULL, list_addr)) {
 					mdb_warn("failed to walk node's active"
 					    " locks");
 				}
 				(void) mdb_dec_indent(SMB_DCMD_INDENT);
 			}
-			mdb_printf("Reference Count :\t%u\n",
-			    node.n_refcnt);
-			mdb_printf("\n");
+			mdb_printf("Reference Count: %u\n\n", node.n_refcnt);
 		} else {
-			mdb_printf("%?p %?p %18s %5d %5d %4d\n",
+			mdb_printf("%-?p %-?p %-18s %-6d %-6d %-6d\n",
 			    addr, node.vp, od_name, node.n_ofile_list.ll_count,
 			    node.n_lock_list.ll_count, node.n_refcnt);
-			if (print_full_path) {
-				if (mdb_vread(&vnode, sizeof (vnode_t),
-				    (uintptr_t)node.vp) ==
-				    sizeof (vnode_t)) {
-					if (mdb_readstr(path_name, 1024,
-					    (uintptr_t)vnode.v_path)) {
-						mdb_printf("\t%s\n",
-						    path_name);
-					}
-				}
-			}
+			if (print_full_path)
+				mdb_printf("\t%s\n", path_name);
 		}
 		if (stack_trace && node.n_audit_buf) {
 			int ctr;
 			smb_audit_buf_node_t *anb;
 
 			anb = mdb_alloc(sizeof (smb_audit_buf_node_t),
-			    UM_SLEEP);
+			    UM_SLEEP | UM_GC);
 
 			if (mdb_vread(anb, sizeof (*anb),
 			    (uintptr_t)node.n_audit_buf) != sizeof (*anb)) {
-				mdb_free(anb, sizeof (smb_audit_buf_node_t));
 				mdb_warn("failed to read audit buffer");
 				return (DCMD_ERR);
 			}
@@ -457,7 +1457,6 @@
 				anb->anb_index &= anb->anb_max_index;
 				ctr--;
 			}
-			mdb_free(anb, sizeof (smb_audit_buf_node_t));
 		}
 	} else {
 		mdb_warn("failed to read struct smb_node at %p", addr);
@@ -467,208 +1466,52 @@
 	return (DCMD_OK);
 }
 
-static void
-smb_session_help(void)
+/*
+ * Initialize the smb_node_t walker by reading the value of smb_node_hash_table
+ * in the kernel's symbol table. Only global walk supported.
+ */
+static int
+smb_node_walk_init(mdb_walk_state_t *wsp)
 {
-	mdb_printf(
-	    "Display the contents of smb_session_t, with optional"
-	    " filtering.\n\n");
-	mdb_dec_indent(2);
-	mdb_printf("%<b>OPTIONS%</b>\n");
-	mdb_inc_indent(2);
-	mdb_printf(
-	    "-v\tDisplay verbose smb_session information\n"
-	    "-r\tDisplay the list of smb requests attached\n"
-	    "-u\tDisplay the list of users attached\n");
+	GElf_Sym	sym;
+	int		i;
+	uintptr_t	node_hash_table_addr;
+
+	if (wsp->walk_addr == NULL) {
+		if (mdb_lookup_by_name("smb_node_hash_table", &sym) == -1) {
+			mdb_warn("failed to find 'smb_node_hash_table'");
+			return (WALK_ERR);
+		}
+		node_hash_table_addr = (uintptr_t)sym.st_value;
+	} else {
+		mdb_printf("smb_node walk only supports global walks\n");
+		return (WALK_ERR);
+	}
+
+	for (i = 0; i < SMBND_HASH_MASK + 1; i++) {
+		wsp->walk_addr = node_hash_table_addr +
+		    (i * sizeof (smb_llist_t)) + offsetof(smb_llist_t, ll_list);
+		if (mdb_layered_walk("list", wsp) == -1) {
+			mdb_warn("failed to walk 'list'");
+			return (WALK_ERR);
+		}
+	}
+
+	return (WALK_NEXT);
+}
+
+static int
+smb_node_walk_step(mdb_walk_state_t *wsp)
+{
+	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
+	    wsp->walk_cbdata));
 }
 
 /*
- * ::smb_session
- *
- * smb_session dcmd - Print out the smb_session structure.
+ * *****************************************************************************
+ * ****************************** smb_lock_t ***********************************
+ * *****************************************************************************
  */
-/*ARGSUSED*/
-static int
-smb_session(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
-	smb_session_t	session;
-	int		print_requests = FALSE;
-	int		print_users = FALSE;
-	int		verbose = FALSE;
-	uintptr_t	list_addr;
-
-	if (mdb_getopts(argc, argv,
-	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
-	    'r', MDB_OPT_SETBITS, TRUE, &print_requests,
-	    'u', MDB_OPT_SETBITS, TRUE, &print_users,
-	    NULL) != argc)
-		return (DCMD_USAGE);
-
-	/*
-	 * If no smb_session address was specified on the command line, we can
-	 * print out all smb sessions by invoking the smb_session walker, using
-	 * this dcmd itself as the callback.
-	 */
-	if (!(flags & DCMD_ADDRSPEC)) {
-		if (mdb_walk_dcmd("smb_session_nbt_rdy", "smb_session",
-		    argc, argv) == -1) {
-			mdb_warn("failed to walk NBT ready 'smb_session'");
-			return (DCMD_ERR);
-		}
-		if (mdb_walk_dcmd("smb_session_tcp_rdy", "smb_session",
-		    argc, argv) == -1) {
-			mdb_warn("failed to walk TCP ready 'smb_session'");
-			return (DCMD_ERR);
-		}
-		if (mdb_walk_dcmd("smb_session_nbt_act", "smb_session",
-		    argc, argv) == -1) {
-			mdb_warn("failed to walk NBT active 'smb_session'");
-			return (DCMD_ERR);
-		}
-		if (mdb_walk_dcmd("smb_session_tcp_act", "smb_session",
-		    argc, argv) == -1) {
-			mdb_warn("failed to walk TCP active 'smb_session'");
-			return (DCMD_ERR);
-		}
-		return (DCMD_OK);
-	}
-
-	/*
-	 * For each smb_session, we just need to read the smb_session_t struct,
-	 * read and then print out the following fields.
-	 */
-	if (mdb_vread(&session, sizeof (session), addr) == sizeof (session)) {
-		/*
-		 * If this is the first invocation of the command, print a nice
-		 * header line for the output that will follow.
-		 */
-		if (DCMD_HDRSPEC(flags)) {
-			if (verbose)
-				mdb_printf("SMB session information:\n\n");
-			else
-				mdb_printf("%<u>%-?s %16s %16s %5s %10s%</u>\n",
-				    "Sessions:", "CLIENT_IP_ADDR",
-				    "LOCAL_IP_ADDR", "KID", "STATE");
-		}
-
-		if (verbose) {
-			mdb_printf("IP address      :\t%I\n",
-			    session.ipaddr);
-			mdb_printf("Local IP Address:\t%I\n",
-			    session.local_ipaddr);
-			mdb_printf("Session KID     :\t%u\n",
-			    session.s_kid);
-			mdb_printf("Workstation Name:\t%s\n",
-			    session.workstation);
-			mdb_printf("Session state   :\t%u\n",
-			    session.s_state);
-			mdb_printf("users           :\t%u\n",
-			    session.s_user_list.ll_count);
-			mdb_printf("trees           :\t%u\n",
-			    session.s_tree_cnt);
-			mdb_printf("files           :\t%u\n",
-			    session.s_file_cnt);
-			mdb_printf("shares          :\t%u\n",
-			    session.s_dir_cnt);
-			mdb_printf("xa count        :\t%u\n\n",
-			    session.s_xa_list.ll_count);
-			mdb_printf("\n");
-		} else {
-			mdb_printf("%?p %16I %16I %5u %10u\n", addr,
-			    session.ipaddr, session.local_ipaddr,
-			    session.s_kid, session.s_state);
-		}
-	} else {
-		mdb_warn("failed to read struct smb_session at %p", &session);
-		return (DCMD_ERR);
-	}
-
-	if (print_requests) {
-		(void) mdb_inc_indent(SMB_DCMD_INDENT);
-		list_addr = addr + offsetof(smb_session_t, s_req_list) +
-		    offsetof(smb_slist_t, sl_list);
-		if (mdb_pwalk_dcmd("list", "smb_request", 0, NULL, list_addr)) {
-			mdb_warn("failed to walk request list\n");
-			(void) mdb_dec_indent(SMB_DCMD_INDENT);
-			return (DCMD_ERR);
-		}
-		(void) mdb_dec_indent(SMB_DCMD_INDENT);
-	}
-
-	if (print_users) {
-		(void) mdb_inc_indent(SMB_DCMD_INDENT);
-		list_addr = addr + offsetof(smb_session_t, s_user_list) +
-		    offsetof(smb_llist_t, ll_list);
-		if (mdb_pwalk_dcmd("list", "smb_user", 0, NULL, list_addr)) {
-			mdb_warn("failed to walk user list\n");
-			(void) mdb_dec_indent(SMB_DCMD_INDENT);
-			return (DCMD_ERR);
-		}
-		(void) mdb_dec_indent(SMB_DCMD_INDENT);
-	}
-
-	return (DCMD_OK);
-}
-
-static int
-smb_request(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
-	smb_request_t	request;
-	int		verbose = FALSE;
-
-	if (mdb_getopts(argc, argv,
-	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
-	    NULL) != argc)
-		return (DCMD_USAGE);
-
-	/*
-	 * An smb_requets_t address must be specified.
-	 */
-	if (!(flags & DCMD_ADDRSPEC))
-		return (DCMD_USAGE);
-
-	/*
-	 * If this is the first invocation of the command, print a nice
-	 * header line for the output that will follow.
-	 */
-	if (DCMD_HDRSPEC(flags)) {
-		if (verbose)
-			mdb_printf("SMB request information:\n\n");
-		else
-			mdb_printf("%<u>%-?s %4s %6s %4s %4s %4s %4s%</u>\n",
-			    "Requests: ", "COM", "STATE",
-			    "TID", "PID", "UID", "MID");
-	}
-
-	if (mdb_vread(&request, sizeof (request), addr) == sizeof (request)) {
-		if (verbose) {
-			mdb_printf("First SMB COM    :\t%I\n",
-			    request.first_smb_com);
-			mdb_printf("State            :\t%I\n",
-			    request.sr_state);
-			mdb_printf("Tree ID          :\t%u\n",
-			    request.smb_tid);
-			mdb_printf("Process ID       :\t%u\n",
-			    request.smb_pid);
-			mdb_printf("User ID          :\t%u\n",
-			    request.smb_uid);
-			mdb_printf("Multiplex ID     :\t%u\n",
-			    request.smb_mid);
-			mdb_printf("\n");
-		} else {
-			mdb_printf("%?p %04x %6x %04x %04x %04x"
-			    " %04x\n", addr,
-			    request.first_smb_com, request.sr_state,
-			    request.smb_tid, request.smb_pid,
-			    request.smb_uid, request.smb_mid);
-		}
-	} else {
-		mdb_warn("failed to read struct smb_request at %p", addr);
-		return (DCMD_ERR);
-	}
-
-	return (DCMD_OK);
-}
 
 static int
 smb_lock(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
@@ -761,380 +1604,6 @@
 	return (DCMD_OK);
 }
 
-static void
-smb_user_help(void)
-{
-	mdb_printf(
-	    "Display the contents of smb_user_t, with optional filtering.\n\n");
-	mdb_dec_indent(2);
-	mdb_printf("%<b>OPTIONS%</b>\n");
-	mdb_inc_indent(2);
-	mdb_printf(
-	    "-v\tDisplay verbose smb_user information\n"
-	    "-q\tDon't Display the contents of the smb_user. This option "
-	    "should be\n\tused in conjunction with -d or -f\n"
-	    "-d\tDisplay the list of smb_odirs attached\n"
-	    "-f\tDisplay the list of smb_ofiles attached\n"
-	    "-t\tDisplay the list of smb_trees attached\n");
-}
-
-static int
-smb_user(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
-	smb_user_t	user;
-	int		print_odir = FALSE;
-	int		print_ofile = FALSE;
-	int		print_tree = FALSE;
-	int		verbose = FALSE;
-	int		quiet = FALSE;
-	uintptr_t	list_addr;
-	int		new_argc;
-	mdb_arg_t	new_argv[3];
-
-	if (mdb_getopts(argc, argv,
-	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
-	    'q', MDB_OPT_SETBITS, TRUE, &quiet,
-	    'd', MDB_OPT_SETBITS, TRUE, &print_odir,
-	    'f', MDB_OPT_SETBITS, TRUE, &print_ofile,
-	    't', MDB_OPT_SETBITS, TRUE, &print_tree,
-	    NULL) != argc)
-		return (DCMD_USAGE);
-
-	/*
-	 * An smb_user address must be specified on the command line.
-	 */
-	if (!(flags & DCMD_ADDRSPEC))
-		return (DCMD_USAGE);
-
-	/*
-	 * If this is the first invocation of the command, print a nice
-	 * header line for the output that will follow.
-	 */
-	if (DCMD_HDRSPEC(flags) && !quiet) {
-		if (verbose)
-			mdb_printf("SMB user information:\n\n");
-		else
-			mdb_printf("%<u>%-?s %4s %6s %8s %16s %8s   %s%</u>\n",
-			    "Users:", "UID", "STATE", "FLAGS", "CRED",
-			    "REFCNT", "ACCOUNT");
-	}
-
-	if (mdb_vread(&user, sizeof (user), addr) !=  sizeof (user)) {
-		mdb_warn("failed to read struct smb_user at %?p", addr);
-		return (DCMD_ERR);
-	}
-
-	if (!quiet) {
-		char domain[SMB_PI_MAX_DOMAIN];
-		char account[SMB_PI_MAX_USERNAME];
-		int valid_domain = 0, valid_account = 0;
-
-		if (mdb_vread(domain, user.u_domain_len,
-		    (uintptr_t)user.u_domain) == user.u_domain_len)
-			valid_domain = 1;
-		if (mdb_vread(account, user.u_name_len,
-		    (uintptr_t)user.u_name) == user.u_name_len)
-			valid_account = 1;
-
-		if (verbose) {
-			mdb_printf("User ID          :\t%04x\n",
-			    user.u_uid);
-			mdb_printf("State            :\t%d\n",
-			    user.u_state);
-			mdb_printf("Flags            :\t%08x\n",
-			    user.u_flags);
-			mdb_printf("Privileges       :\t%08x\n",
-			    user.u_privileges);
-			mdb_printf("Credential       :\t%llx\n",
-			    user.u_cred);
-			mdb_printf("Reference Count  :\t%d\n",
-			    user.u_refcnt);
-			if (valid_domain && valid_account)
-				mdb_printf("User Account     :\t%s\\%s\n",
-				    domain, account);
-			mdb_printf("\n");
-		} else {
-			mdb_printf("%?p %04x %6d %08x %?p %8d   %s\\%s\n",
-			    addr, user.u_uid, user.u_state, user.u_flags,
-			    user.u_cred, user.u_refcnt,
-			    valid_domain ? domain : "UNKNOWN",
-			    valid_account ? account : "UNKNOWN");
-		}
-	}
-
-	new_argc = 0;
-	if (!print_tree) {
-		new_argv[new_argc].a_type = MDB_TYPE_STRING;
-		new_argv[new_argc].a_un.a_str = "-q";
-		new_argc++;
-	}
-	if (print_ofile) {
-		new_argv[new_argc].a_type = MDB_TYPE_STRING;
-		new_argv[new_argc].a_un.a_str = "-f";
-		new_argc++;
-	}
-	if (print_odir) {
-		new_argv[new_argc].a_type = MDB_TYPE_STRING;
-		new_argv[new_argc].a_un.a_str = "-d";
-		new_argc++;
-	}
-
-	if (print_tree || print_ofile || print_odir) {
-		(void) mdb_inc_indent(SMB_DCMD_INDENT);
-		list_addr = addr + offsetof(smb_user_t, u_tree_list) +
-		    offsetof(smb_llist_t, ll_list);
-		if (mdb_pwalk_dcmd("list", "smb_tree", new_argc, new_argv,
-		    list_addr)) {
-			mdb_warn("failed to walk tree list\n");
-			(void) mdb_dec_indent(SMB_DCMD_INDENT);
-			return (DCMD_ERR);
-		}
-		(void) mdb_dec_indent(SMB_DCMD_INDENT);
-	}
-
-	return (DCMD_OK);
-}
-
-static void
-smb_tree_help(void)
-{
-	mdb_printf(
-	    "Display the contents of smb_tree_t, with optional filtering.\n\n");
-	mdb_dec_indent(2);
-	mdb_printf("%<b>OPTIONS%</b>\n");
-	mdb_inc_indent(2);
-	mdb_printf(
-	    "-v\tDisplay verbose smb_tree information\n"
-	    "-q\tDon't Display the contents of the smb_tree. This option "
-	    "should be\n\tused in conjunction with -d or -f\n"
-	    "-d\tDisplay the list of smb_odirs attached\n"
-	    "-f\tDisplay the list of smb_ofiles attached\n");
-}
-
-static int
-smb_tree(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
-	smb_tree_t	tree;
-	int		print_odir = FALSE;
-	int		print_ofile = FALSE;
-	int		verbose = FALSE;
-	int		quiet = FALSE;
-	uintptr_t	list_addr;
-
-	if (mdb_getopts(argc, argv,
-	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
-	    'd', MDB_OPT_SETBITS, TRUE, &print_odir,
-	    'f', MDB_OPT_SETBITS, TRUE, &print_ofile,
-	    'q', MDB_OPT_SETBITS, TRUE, &quiet,
-	    NULL) != argc)
-		return (DCMD_USAGE);
-
-	/*
-	 * If no smb_session address was specified on the command line, we can
-	 * print out all smb sessions by invoking the smb_session walker, using
-	 * this dcmd itself as the callback.
-	 */
-	if (!(flags & DCMD_ADDRSPEC))
-		return (DCMD_USAGE);
-
-	/*
-	 * If this is the first invocation of the command, print a nice
-	 * header line for the output that will follow.
-	 */
-	if (DCMD_HDRSPEC(flags)) {
-		if (verbose)
-			mdb_printf("SMB tree information:\n\n");
-		else
-			mdb_printf("%<u>%-?s %4s %6s %16s %10s%</u>\n",
-			    "Trees:", "TID", "STATE", "SMB NODE",
-			    "SHARE NAME");
-	}
-
-	/*
-	 * Read tree and print some of the fields
-	 */
-	if (mdb_vread(&tree, sizeof (tree), addr) != sizeof (tree)) {
-		mdb_warn("failed to read struct smb_tree at %p", addr);
-		return (DCMD_ERR);
-	}
-	if (!quiet) {
-		if (verbose) {
-			mdb_printf("Tree ID          :\t%04x\n",
-			    tree.t_tid);
-			mdb_printf("State            :\t%d\n",
-			    tree.t_state);
-			mdb_printf("Share name       :\t%s\n",
-			    tree.t_sharename);
-			mdb_printf("Resource         :\t%s\n",
-			    tree.t_resource);
-			mdb_printf("Umask            :\t%04x\n",
-			    tree.t_umask);
-			mdb_printf("Access           :\t%04x\n",
-			    tree.t_access);
-			mdb_printf("Flags            :\t%08x\n",
-			    tree.t_flags);
-			mdb_printf("SMB Node         :\t%llx\n",
-			    tree.t_snode);
-			mdb_printf("Reference Count  :\t%d\n",
-			    tree.t_refcnt);
-			mdb_printf("\n");
-		} else {
-			mdb_printf("%?p %04x %6d %16llx %s\n", addr,
-			    tree.t_tid, tree.t_state, tree.t_snode,
-			    tree.t_sharename);
-		}
-	}
-
-	if (print_odir) {
-		(void) mdb_inc_indent(SMB_DCMD_INDENT);
-		list_addr = addr + offsetof(smb_tree_t, t_odir_list) +
-		    offsetof(smb_llist_t, ll_list);
-		if (mdb_pwalk_dcmd("list", "smb_odir", 0, NULL, list_addr)) {
-			mdb_warn("failed to walk odir list\n");
-			(void) mdb_dec_indent(SMB_DCMD_INDENT);
-			return (DCMD_ERR);
-		}
-		(void) mdb_dec_indent(SMB_DCMD_INDENT);
-	}
-
-	if (print_ofile) {
-		(void) mdb_inc_indent(SMB_DCMD_INDENT);
-		list_addr = addr + offsetof(smb_tree_t, t_ofile_list) +
-		    offsetof(smb_llist_t, ll_list);
-		if (mdb_pwalk_dcmd("list", "smb_ofile", 0, NULL, list_addr)) {
-			mdb_warn("failed to walk ofile list\n");
-			(void) mdb_dec_indent(SMB_DCMD_INDENT);
-			return (DCMD_ERR);
-		}
-		(void) mdb_dec_indent(SMB_DCMD_INDENT);
-	}
-
-	return (DCMD_OK);
-}
-
-static int
-smb_odir(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
-	smb_odir_t	odir;
-	int		verbose = FALSE;
-
-	if (mdb_getopts(argc, argv,
-	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
-	    NULL) != argc)
-		return (DCMD_USAGE);
-
-	/*
-	 * If no smb_session address was specified on the command line, we can
-	 * print out all smb sessions by invoking the smb_session walker, using
-	 * this dcmd itself as the callback.
-	 */
-	if (!(flags & DCMD_ADDRSPEC))
-		return (DCMD_USAGE);
-
-	/*
-	 * If this is the first invocation of the command, print a nice
-	 * header line for the output that will follow.
-	 */
-	if (DCMD_HDRSPEC(flags)) {
-		if (verbose)
-			mdb_printf("SMB odir information:\n\n");
-		else
-			mdb_printf("%<u>%-?s %8s %?s %10s%</u>\n",
-			    "odir:", "STATE", "SMB NODE", "PATTERN");
-	}
-
-	/*
-	 * For each smb_session, we just need to read the smb_session_t struct,
-	 * read and then print out the following fields.
-	 */
-	if (mdb_vread(&odir, sizeof (odir), addr) == sizeof (odir)) {
-		if (verbose) {
-			mdb_printf("State            :\t%d\n",
-			    odir.d_state);
-			mdb_printf("Pattern          :\t%s\n",
-			    odir.d_pattern);
-			mdb_printf("SMB Node         :\t%s\n",
-			    odir.d_dir_snode);
-			mdb_printf("\n");
-		} else {
-			mdb_printf("%?p %8d %16llx %s\n", addr,
-			    odir.d_state, odir.d_dir_snode, odir.d_pattern);
-		}
-	} else {
-		mdb_warn("failed to read struct smb_odir at %p", addr);
-		return (DCMD_ERR);
-	}
-
-	return (DCMD_OK);
-}
-
-static int
-smb_ofile(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
-{
-	smb_ofile_t ofile;
-	int verbose = FALSE;
-
-	if (mdb_getopts(argc, argv,
-	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
-	    NULL) != argc)
-		return (DCMD_USAGE);
-
-	/*
-	 * If no smb_session address was specified on the command line, we can
-	 * print out all smb sessions by invoking the smb_session walker, using
-	 * this dcmd itself as the callback.
-	 */
-	if (!(flags & DCMD_ADDRSPEC))
-		return (DCMD_USAGE);
-
-	/*
-	 * If this is the first invocation of the command, print a nice
-	 * header line for the output that will follow.
-	 */
-	if (DCMD_HDRSPEC(flags)) {
-		if (verbose)
-			mdb_printf("SMB ofile information:\n\n");
-		else
-			mdb_printf("%<u>%-?s %04s %8s %?s %8s %?s%</u>\n",
-			    "ofiles:", "FID", "STATE", "SMB NODE", "FLAGS",
-			    "CRED");
-	}
-
-	/*
-	 * For each smb_session, we just need to read the smb_session_t struct,
-	 * read and then print out the following fields.
-	 */
-	if (mdb_vread(&ofile, sizeof (ofile), addr) == sizeof (ofile)) {
-		if (verbose) {
-			mdb_printf("Ofile ID         :\t%04x\n",
-			    ofile.f_fid);
-			mdb_printf("State            :\t%d\n",
-			    ofile.f_state);
-			mdb_printf("SMB Node         :\t%llx\n",
-			    ofile.f_node);
-			mdb_printf("LLF Offset       :\t%llx (%s)\n",
-			    ofile.f_llf_pos,
-			    ((ofile.f_flags & SMB_OFLAGS_LLF_POS_VALID) ?
-			    "Valid" : "Invalid"));
-			mdb_printf("FLAGS            :\t%08x\n",
-			    ofile.f_flags);
-			mdb_printf("Credential       :\t%llx\n",
-			    ofile.f_cr);
-			mdb_printf("\n");
-		} else {
-			mdb_printf("%?p %04x %8d %16llx %08x %?\n", addr,
-			    ofile.f_fid, ofile.f_state, ofile.f_node,
-			    ofile.f_flags, ofile.f_cr);
-		}
-	} else {
-		mdb_warn("failed to read struct smb_odir at %p", addr);
-		return (DCMD_ERR);
-	}
-
-	return (DCMD_OK);
-}
-
-
 /*
  * ::smb_dispatch_stats
  *
@@ -1142,8 +1611,7 @@
  */
 /*ARGSUSED*/
 static int
-smb_stats(uintptr_t addr, uint_t flags, int argc,
-    const mdb_arg_t *argv)
+smb_stats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 {
 	smb_dispatch_table_t	*disp;
 	GElf_Sym		sym;
@@ -1176,72 +1644,497 @@
 }
 
 /*
- * MDB module linkage information:
- *
- * We declare a list of structures describing our dcmds, a list of structures
- * describing our walkers and a function named _mdb_init to return a pointer
- * to our module information.
+ * *****************************************************************************
+ * ******************************** smb_ace_t **********************************
+ * *****************************************************************************
  */
-static const mdb_dcmd_t dcmds[] = {
-	{   "smb_info", "[-c]",
-	    "print smb_info information", smb_information },
-	{   "smb_node", "?[-vps]",
-	    "print smb_node_t information", smb_node, smb_node_help },
-	{   "smb_session", "?[-vru]",
-	    "print smb_session_t information", smb_session, smb_session_help},
-	{   "smb_request", ":[-v]",
-	    "print smb_request_t information", smb_request },
-	{   "smb_lock", ":[-v]",
-	    "print smb_lock_t information", smb_lock },
-	{   "smb_user", ":[-vdftq]",
-	    "print smb_user_t information", smb_user, smb_user_help },
-	{   "smb_tree", ":[-vdfq]",
-	    "print smb_tree_t information", smb_tree, smb_tree_help },
-	{   "smb_odir", ":[-v]",
-	    "print smb_odir_t information", smb_odir },
-	{   "smb_ofile", "[-v]",
-	    "print smb_odir_t information", smb_ofile },
-	{   "smb_stats", NULL,
-	    "print all smb dispatched requests statistics",
-	    smb_stats },
-	{ NULL }
+static const ace_type_entry_t	ace_types[ACE_TYPE_TABLEN] =
+{
+	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE),
+	ACE_TYPE_ENTRY(0x11),
+	ACE_TYPE_ENTRY(0x12),
+	ACE_TYPE_ENTRY(0x13),
+	ACE_TYPE_ENTRY(0x14),
+	ACE_TYPE_ENTRY(0x15),
+	ACE_TYPE_ENTRY(0x16),
+	ACE_TYPE_ENTRY(0x17),
+	ACE_TYPE_ENTRY(0x18),
+	ACE_TYPE_ENTRY(0x19),
+	ACE_TYPE_ENTRY(0x1A),
+	ACE_TYPE_ENTRY(0x1B),
+	ACE_TYPE_ENTRY(0x1C),
+	ACE_TYPE_ENTRY(0x1D),
+	ACE_TYPE_ENTRY(0x1E),
+	ACE_TYPE_ENTRY(0x1F)
+};
+
+static const mdb_bitmask_t ace_flag_bits[] = {
+	{ "OBJECT_INHERIT_ACE", OBJECT_INHERIT_ACE, OBJECT_INHERIT_ACE },
+	{ "CONTAINER_INHERIT_ACE", CONTAINER_INHERIT_ACE,
+	    CONTAINER_INHERIT_ACE },
+	{ "NO_PROPOGATE_INHERIT_ACE", NO_PROPOGATE_INHERIT_ACE,
+	    NO_PROPOGATE_INHERIT_ACE },
+	{ "INHERIT_ONLY_ACE", INHERIT_ONLY_ACE, INHERIT_ONLY_ACE },
+	{ "INHERITED_ACE", INHERITED_ACE, INHERITED_ACE },
+	{ "SUCCESSFUL_ACCESS_ACE_FLAG", SUCCESSFUL_ACCESS_ACE_FLAG,
+	    SUCCESSFUL_ACCESS_ACE_FLAG },
+	{ "FAILED_ACCESS_ACE_FLAG", FAILED_ACCESS_ACE_FLAG,
+	    FAILED_ACCESS_ACE_FLAG },
+	{ NULL, 0, 0 }
 };
 
-static const mdb_walker_t walkers[] = {
-	{  "smb_session_nbt_rdy", "walk list of sessions ready",
-	    smb_session_nbt_rdy_walk_init,
-	    smb_session_walk_step,
-	    NULL,
-	    NULL },
-	{  "smb_session_nbt_act", "walk list of active sessions",
-	    smb_session_nbt_act_walk_init,
-	    smb_session_walk_step,
-	    NULL,
-	    NULL },
-	{  "smb_session_tcp_rdy", "walk list of sessions ready",
-	    smb_session_tcp_rdy_walk_init,
-	    smb_session_walk_step,
-	    NULL,
-	    NULL },
-	{  "smb_session_tcp_act", "walk list of active sessions",
-	    smb_session_tcp_act_walk_init,
-	    smb_session_walk_step,
-	    NULL,
-	    NULL },
-	{  "smb_node", "walk list of smb_node_t structures",
-	    smb_node_walk_init,
-	    smb_node_walk_step,
-	    NULL,
-	    NULL },
-	{ NULL }
-};
+/*
+ * ::smbace
+ */
+static int
+smb_ace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	smb_ace_t	ace;
+	int		verbose = FALSE;
+	const char	*ptr;
+	int		rc;
+
+	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose,
+	    NULL) != argc)
+		return (DCMD_USAGE);
+
+	/*
+	 * An smb_ace address is required.
+	 */
+	if (!(flags & DCMD_ADDRSPEC))
+		return (DCMD_USAGE);
+
+	if (mdb_vread(&ace, sizeof (ace), addr) != sizeof (ace)) {
+		mdb_warn("failed to read struct smb_ace at %p", addr);
+		return (DCMD_ERR);
+	}
+
+	if (verbose) {
+		if (ace.se_hdr.se_type < ACE_TYPE_TABLEN)
+			ptr = ace_types[ace.se_hdr.se_type].ace_type_sting;
+		else
+			ptr = "Unknown";
+
+		mdb_printf("ACE Type: 0x%02x (%s)\n", ace.se_hdr.se_type, ptr);
+		mdb_printf("ACE Flags: %b\n", (int)ace.se_hdr.se_flags,
+		    ace_flag_bits);
+		mdb_printf("ACE Wire Size: 0x%04x\n", ace.se_hdr.se_bsize);
+		mdb_printf("ACE Mask: 0x%08x\n", ace.se_mask);
+		mdb_printf("ACE SID: ");
+	} else {
+		if (DCMD_HDRSPEC(flags))
+			mdb_printf(
+			    "%<b>%<u>%?-s %-4s %-4s %-8s %s%</u>%</b>\n",
+			    "ACE", "TYPE", "FLAGS", "MASK", "SID");
+		mdb_printf("%?p 0x%02x 0x%02x 0x%08x ", addr,
+		    ace.se_hdr.se_type, ace.se_hdr.se_flags, ace.se_mask);
+	}
+	rc = smb_sid_print((uintptr_t)ace.se_sid);
+	mdb_printf("\n");
+	return (rc);
+}
+
+static int
+smb_ace_walk_init(mdb_walk_state_t *wsp)
+{
+	if (wsp->walk_addr == 0) {
+		mdb_printf("smb_ace walk only supports local walks\n");
+		return (WALK_ERR);
+	}
+
+	wsp->walk_addr += offsetof(smb_acl_t, sl_sorted);
+
+	if (mdb_layered_walk("list", wsp) == -1) {
+		mdb_warn("failed to walk list of ACEs");
+		return (WALK_ERR);
+	}
+
+	return (WALK_NEXT);
+}
+
+static int
+smb_ace_walk_step(mdb_walk_state_t *wsp)
+{
+	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
+	    wsp->walk_cbdata));
+}
+
+/*
+ * *****************************************************************************
+ * ******************************** smb_acl_t **********************************
+ * *****************************************************************************
+ */
+
+/*
+ * ::smbacl
+ */
+static int
+smb_acl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	smb_acl_t	acl;
+
+	/* An smb_acl address is required. */
+	if (!(flags & DCMD_ADDRSPEC))
+		return (DCMD_USAGE);
+
+	if (mdb_vread(&acl, sizeof (acl), addr) != sizeof (acl)) {
+		mdb_warn("failed to read struct smb_acl at %p", addr);
+		return (DCMD_ERR);
+	}
+
+	mdb_printf("ACL Revision: %d\n", acl.sl_revision);
+	mdb_printf("ACL Size on Wire: %d\n", acl.sl_bsize);
+	mdb_printf("ACL Number of ACEs: %d\n", acl.sl_acecnt);
+
+	(void) mdb_inc_indent(SMB_DCMD_INDENT);
+	if (mdb_pwalk_dcmd("smbace_walker", "smbace", argc, argv, addr)) {
+		(void) mdb_dec_indent(SMB_DCMD_INDENT);
+		mdb_warn("failed to walk list of ACEs for ACL %p", addr);
+		return (DCMD_ERR);
+	}
+	(void) mdb_dec_indent(SMB_DCMD_INDENT);
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ********************************* smb_sd_t **********************************
+ * *****************************************************************************
+ */
+
+/*
+ * ::smbsd
+ */
+static int
+smb_sd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	smb_sd_t	sd;
+	int		rc;
+
+	/*
+	 * An smb_sid address is required.
+	 */
+	if (!(flags & DCMD_ADDRSPEC))
+		return (DCMD_USAGE);
+
+	if (mdb_vread(&sd, sizeof (sd), addr) != sizeof (sd)) {
+		mdb_warn("failed to read struct smb_sd at %p", addr);
+		return (DCMD_ERR);
+	}
+
+	mdb_printf("SD Revision: %d\n", sd.sd_revision);
+	mdb_printf("SD Control: %04x\n", sd.sd_control);
+	if (sd.sd_control & SE_OWNER_DEFAULTED)
+		mdb_printf("\t    SE_OWNER_DEFAULTED\n");
+	if (sd.sd_control & SE_GROUP_DEFAULTED)
+		mdb_printf("\t    SE_GROUP_DEFAULTED\n");
+	if (sd.sd_control & SE_DACL_PRESENT)
+		mdb_printf("\t    SE_DACL_PRESENT\n");
+	if (sd.sd_control & SE_DACL_DEFAULTED)
+		mdb_printf("\t    SE_DACL_DEFAULTED\n");
+	if (sd.sd_control & SE_SACL_PRESENT)
+		mdb_printf("\t    SE_SACL_PRESENT\n");
+	if (sd.sd_control & SE_SACL_DEFAULTED)
+		mdb_printf("\t    SE_SACL_DEFAULTED\n");
+	if (sd.sd_control & SE_DACL_AUTO_INHERIT_REQ)
+		mdb_printf("\t    SE_DACL_AUTO_INHERIT_REQ\n");
+	if (sd.sd_control & SE_SACL_AUTO_INHERIT_REQ)
+		mdb_printf("\t    SE_SACL_AUTO_INHERIT_REQ\n");
+	if (sd.sd_control & SE_DACL_AUTO_INHERITED)
+		mdb_printf("\t    SE_DACL_AUTO_INHERITED\n");
+	if (sd.sd_control & SE_SACL_AUTO_INHERITED)
+		mdb_printf("\t    SE_SACL_AUTO_INHERITED\n");
+	if (sd.sd_control & SE_DACL_PROTECTED)
+		mdb_printf("\t    SE_DACL_PROTECTED\n");
+	if (sd.sd_control & SE_SACL_PROTECTED)
+		mdb_printf("\t    SE_SACL_PROTECTED\n");
+	if (sd.sd_control & SE_SELF_RELATIVE)
+		mdb_printf("\t    SE_SELF_RELATIVE\n");
+
+	mdb_printf("SID of Owner: ");
+	rc = smb_sid_print((uintptr_t)sd.sd_owner);
+	if (rc != DCMD_OK)
+		return (rc);
+	mdb_printf("\nSID of Group: ");
+	rc = smb_sid_print((uintptr_t)sd.sd_group);
+	if (rc != DCMD_OK)
+		return (rc);
+	mdb_printf("\n");
+
+	if (sd.sd_control & SE_SACL_PRESENT && sd.sd_sacl) {
+		mdb_printf("%<b>%<u>System ACL%</u>%</b>\n");
+		(void) mdb_inc_indent(SMB_DCMD_INDENT);
+		rc = mdb_call_dcmd("smbacl", (uintptr_t)sd.sd_sacl, flags,
+		    argc, argv);
+		(void) mdb_dec_indent(SMB_DCMD_INDENT);
+		if (rc != DCMD_OK)
+			return (rc);
+	}
+	if (sd.sd_control & SE_DACL_PRESENT && sd.sd_dacl) {
+		mdb_printf("%<b>%<u>Discretionary ACL%</u>%</b>\n");
+		(void) mdb_inc_indent(SMB_DCMD_INDENT);
+		rc = mdb_call_dcmd("smbacl", (uintptr_t)sd.sd_dacl, flags,
+		    argc, argv);
+		(void) mdb_dec_indent(SMB_DCMD_INDENT);
+		if (rc != DCMD_OK)
+			return (rc);
+	}
+
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ********************************* smb_sid_t *********************************
+ * *****************************************************************************
+ */
+
+/*
+ * ::smbsid
+ */
+/*ARGSUSED*/
+static int
+smb_sid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	/*
+	 * An smb_sid address is required.
+	 */
+	if (!(flags & DCMD_ADDRSPEC))
+		return (DCMD_USAGE);
 
-static const mdb_modinfo_t modinfo = {
-	MDB_API_VERSION, dcmds, walkers
-};
+	return (smb_sid_print(addr));
+}
+
+/*
+ * smb_sid_print
+ */
+static int
+smb_sid_print(uintptr_t addr)
+{
+	smb_sid_t	sid;
+	smb_sid_t	*psid;
+	size_t		sid_size;
+	int		i;
+	uint64_t	authority;
+
+	sid_size = offsetof(smb_sid_t, sid_subauth);
+
+	if (mdb_vread(&sid, sid_size, addr) != sid_size) {
+		mdb_warn("failed to read struct smb_sid at %p", addr);
+		return (DCMD_ERR);
+	}
+
+	sid_size += sid.sid_subauthcnt * sizeof (sid.sid_subauth[0]);
+
+	psid = mdb_zalloc(sid_size, UM_SLEEP | UM_GC);
+	if (mdb_vread(psid, sid_size, addr) != sid_size) {
+		mdb_warn("failed to read struct smb_sid at %p", addr);
+		return (DCMD_ERR);
+	}
+
+	mdb_printf("S-%d", psid->sid_revision);
+	authority = 0;
+	for (i = 0; i < NT_SID_AUTH_MAX; i++) {
+		authority += ((uint64_t)psid->sid_authority[i]) <<
+		    (8 * (NT_SID_AUTH_MAX - 1) - i);
+	}
+	mdb_printf("-%ll", authority);
+
+	for (i = 0; i < psid->sid_subauthcnt; i++)
+		mdb_printf("-%d", psid->sid_subauth[i]);
+
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * ********************************* smb_fssd_t ********************************
+ * *****************************************************************************
+ */
+
+/*
+ * ::smbfssd
+ */
+static int
+smb_fssd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	smb_fssd_t	fssd;
+	int		rc;
+
+	/*
+	 * An smb_fssd address is required.
+	 */
+	if (!(flags & DCMD_ADDRSPEC))
+		return (DCMD_USAGE);
+
+	if (mdb_vread(&fssd, sizeof (fssd), addr) != sizeof (fssd)) {
+		mdb_warn("failed to read struct smb_fssd at %p", addr);
+		return (DCMD_ERR);
+	}
+
+	mdb_printf("FSSD secinfo: 0x%x\n", fssd.sd_secinfo);
+	if (fssd.sd_secinfo & SMB_OWNER_SECINFO)
+		mdb_printf("FSSD uid: %d\n", fssd.sd_uid);
+	if (fssd.sd_secinfo & SMB_GROUP_SECINFO)
+		mdb_printf("FSSD gid: %d\n", fssd.sd_gid);
+	if (fssd.sd_secinfo & SMB_SACL_SECINFO && fssd.sd_zsacl) {
+		mdb_printf("%<b>%<u>System ACL%</u>%</b>\n");
+		(void) mdb_inc_indent(SMB_DCMD_INDENT);
+		rc = mdb_call_dcmd("smbacl", (uintptr_t)fssd.sd_zsacl, flags,
+		    argc, argv);
+		(void) mdb_dec_indent(SMB_DCMD_INDENT);
+		if (rc != DCMD_OK)
+			return (rc);
+	}
+	if (fssd.sd_secinfo & SMB_DACL_SECINFO && fssd.sd_zdacl) {
+		mdb_printf("%<b>%<u>Discretionary ACL%</u>%</b>\n");
+		(void) mdb_inc_indent(SMB_DCMD_INDENT);
+		rc = mdb_call_dcmd("smbacl", (uintptr_t)fssd.sd_zdacl, flags,
+		    argc, argv);
+		(void) mdb_dec_indent(SMB_DCMD_INDENT);
+		if (rc != DCMD_OK)
+			return (rc);
+	}
+
+	return (DCMD_OK);
+}
+
+/*
+ * *****************************************************************************
+ * **************************** Utility Funcions *******************************
+ * *****************************************************************************
+ */
 
-const mdb_modinfo_t *
-_mdb_init(void)
+/*
+ * smb_dcmd_getopt
+ *
+ * This function analyzes the arguments passed in and sets the bit corresponding
+ * to the options found in the opts variable.
+ *
+ * Return Value
+ *
+ *	-1	An error occured during the decoding
+ *	0	The decoding was successful
+ */
+static int
+smb_dcmd_getopt(uint_t *opts, int argc, const mdb_arg_t *argv)
+{
+	*opts = 0;
+
+	if (mdb_getopts(argc, argv,
+	    's', MDB_OPT_SETBITS, SMB_OPT_SERVER, opts,
+	    'm', MDB_OPT_SETBITS, SMB_OPT_VFS, opts,
+	    'e', MDB_OPT_SETBITS, SMB_OPT_SESSION, opts,
+	    'r', MDB_OPT_SETBITS, SMB_OPT_REQUEST, opts,
+	    'u', MDB_OPT_SETBITS, SMB_OPT_USER, opts,
+	    't', MDB_OPT_SETBITS, SMB_OPT_TREE, opts,
+	    'f', MDB_OPT_SETBITS, SMB_OPT_OFILE, opts,
+	    'd', MDB_OPT_SETBITS, SMB_OPT_ODIR, opts,
+	    'w', MDB_OPT_SETBITS, SMB_OPT_WALK, opts,
+	    'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, opts,
+	    NULL) != argc)
+		return (-1);
+
+	return (0);
+}
+
+/*
+ * smb_dcmd_setopt
+ *
+ * This function set the arguments corresponding to the bits set in opts.
+ *
+ * Return Value
+ *
+ *	Number of arguments set.
+ */
+static int
+smb_dcmd_setopt(uint_t opts, int max_argc, mdb_arg_t *argv)
 {
-	return (&modinfo);
+	int	i;
+	uint_t	mask = 0x00000001;
+	int	argc = 0;
+
+	for (i = 0; i < SMB_MDB_MAX_OPTS; i++) {
+		if ((opts & mask) && (argc < max_argc)) {
+			argv->a_type = MDB_TYPE_STRING;
+			argv->a_un.a_str = smb_opts[i];
+			argc++;
+			argv++;
+		}
+		mask = mask << 1;
+	}
+	return (argc);
 }
+
+/*
+ * smb_obj_expand
+ */
+static int
+smb_obj_expand(uintptr_t addr, uint_t opts, const smb_exp_t *x, ulong_t indent)
+{
+	int		rc = 0;
+	int		argc;
+	mdb_arg_t	argv[SMB_MDB_MAX_OPTS];
+
+	argc = smb_dcmd_setopt(opts | SMB_OPT_WALK, SMB_MDB_MAX_OPTS, argv);
+
+	(void) mdb_inc_indent(indent);
+	while (x->ex_dcmd) {
+		if (x->ex_mask & opts) {
+			rc = mdb_pwalk_dcmd("list", x->ex_dcmd, argc, argv,
+			    addr + x->ex_offset);
+
+			if (rc) {
+				mdb_warn("failed to walk the list of %s in %p",
+				    x->ex_name, addr + x->ex_offset);
+				break;
+			}
+		}
+		x++;
+	}
+	(void) mdb_dec_indent(indent);
+	return (rc);
+}
+
+/*
+ * smb_obj_list
+ *
+ * Function called by the DCMDs when no address is provided. It expands the
+ * tree under the object type associated with the calling DCMD (based on the
+ * flags passed in).
+ *
+ * Return Value
+ *
+ *	DCMD_OK
+ *	DCMD_ERR
+ */
+static int
+smb_obj_list(const char *name, uint_t opts, uint_t flags)
+{
+	int		argc;
+	mdb_arg_t	argv[SMB_MDB_MAX_OPTS];
+
+	argc = smb_dcmd_setopt(opts, SMB_MDB_MAX_OPTS, argv);
+
+	if (mdb_call_dcmd("smblist", 0, flags, argc, argv)) {
+		mdb_warn("failed to list %s", name);
+		return (DCMD_ERR);
+	}
+	return (DCMD_OK);
+}
--- a/usr/src/cmd/smbsrv/Makefile.smbsrv.defs	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/Makefile.smbsrv.defs	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -31,7 +31,6 @@
 
 OBJS=	$(SRCS:%.c=%.o)
 
-LDLIBS += -lumem
 LDLIBS += -L$(ROOT)/usr/lib/smbsrv
 LDFLAGS += -R/usr/lib/smbsrv
 LINTFLAGS += -xerroff=E_NAME_DEF_NOT_USED2
--- a/usr/src/cmd/smbsrv/smbadm/Makefile	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbadm/Makefile	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -31,7 +31,7 @@
 include ../../Makefile.cmd
 include ../Makefile.smbsrv.defs
 
-LDLIBS += -lsmb
+LDLIBS += -lsmb -lumem
 
 all:		$(PROG)
 
--- a/usr/src/cmd/smbsrv/smbadm/smbadm.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbadm/smbadm.c	Mon Apr 14 10:40:32 2008 -0700
@@ -282,6 +282,7 @@
 	boolean_t join_d = B_FALSE;
 	uint32_t status;
 	char kdom[MAXHOSTNAMELEN];
+	boolean_t override = B_FALSE;
 
 	bzero(&jdi, sizeof (jdi));
 
@@ -360,6 +361,8 @@
 			(void) trim_whitespace(reply);
 			if (strncasecmp(reply, "yes", 3) != 0)
 				return (0);
+
+			override = B_TRUE;
 		}
 	}
 
@@ -386,6 +389,14 @@
 	case NT_STATUS_SUCCESS:
 		(void) printf(gettext("Successfully joined domain '%s'\n"),
 		    jdi.domain_name);
+
+		if (override) {
+			if (smb_getfqdomainname(kdom, sizeof (kdom)) == -1)
+				(void) strlcpy(kdom, jdi.domain_name,
+				    sizeof (kdom));
+
+			(void) smb_config_setstr(SMB_CI_KPASSWD_DOMAIN, kdom);
+		}
 		return (0);
 
 	case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND:
@@ -494,7 +505,7 @@
 static void
 smbadm_group_dump_members(smb_gsid_t *members, int num)
 {
-	char sidstr[NT_SID_FMTBUF_SIZE];
+	char sidstr[SMB_SID_STRSZ];
 	int i;
 
 	if (num == 0) {
@@ -555,11 +566,11 @@
 static void
 smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs)
 {
-	char sidstr[NT_SID_FMTBUF_SIZE];
+	char sidstr[SMB_SID_STRSZ];
 
 	(void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt);
 
-	nt_sid_format2(grp->sg_id.gs_sid, sidstr);
+	smb_sid_tostr(grp->sg_id.gs_sid, sidstr);
 	(void) printf(gettext("\tSID: %s\n"), sidstr);
 
 	if (show_privs)
@@ -617,20 +628,27 @@
 		return (status);
 	}
 
-	status = smb_lgrp_iteropen(&gi);
-	if (status != SMB_LGRP_SUCCESS) {
+	if ((status = smb_lgrp_iteropen(&gi)) != SMB_LGRP_SUCCESS) {
 		(void) fprintf(stderr,
 		    gettext("failed to list groups (%s)\n"),
 		    smb_lgrp_strerror(status));
 		return (status);
 	}
 
-	while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
+	while ((status = smb_lgrp_iterate(&gi, &grp)) == SMB_LGRP_SUCCESS) {
 		smbadm_group_dump(&grp, show_members, show_privs);
 		smb_lgrp_free(&grp);
 	}
+
 	smb_lgrp_iterclose(&gi);
 
+	if (status != SMB_LGRP_NO_MORE) {
+		(void) fprintf(stderr,
+		    gettext("failed to get all the groups (%s)\n"),
+		    smb_lgrp_strerror(status));
+		return (status);
+	}
+
 	return (0);
 }
 
--- a/usr/src/cmd/smbsrv/smbd/Makefile	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbd/Makefile	Mon Apr 14 10:40:32 2008 -0700
@@ -34,7 +34,6 @@
 	smbd_main.c		\
 	smbd_mlsvc_doorsvc.c	\
 	smbd_net.c		\
-	smbd_nicmon.c		\
 	smbd_share_doorsvc.c
 
 include ../../Makefile.cmd
@@ -46,7 +45,7 @@
 
 include ../Makefile.smbsrv.defs
 
-LDLIBS += -lmlsvc -lmlrpc -lsmbrdr -lsmbns -lsmb -lbsm -lnsl -lsocket
+LDLIBS += -lmlsvc -lmlrpc -lsmbrdr -lsmbns -lsmb -lbsm -lnsl -lumem
 
 ROOTSMBDDIR = $(ROOTLIB)/smbsrv
 ROOTSMBDFILE = $(PROG:%=$(ROOTSMBDDIR)/%)
--- a/usr/src/cmd/smbsrv/smbd/smbd.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbd/smbd.h	Mon Apr 14 10:40:32 2008 -0700
@@ -38,9 +38,6 @@
 #include <smbsrv/libsmb.h>
 #include <smbsrv/libmlsvc.h>
 
-extern int smb_nicmon_start(void);
-extern void smb_nicmon_stop(void);
-extern void smb_nicmon_reconfig(void);
 extern int smb_winpipe_doorsvc_start(void);
 extern void smb_winpipe_doorsvc_stop(void);
 extern int smb_lmshrd_srv_start(void);
@@ -60,15 +57,21 @@
 extern uint32_t smbd_join(smb_joininfo_t *);
 
 typedef struct smbd {
-	const char *s_version;		/* smbd version string */
-	const char *s_pname;		/* basename to use for messages */
-	pid_t s_pid;			/* process-ID of current daemon */
-	uid_t s_uid;			/* UID of current daemon */
-	gid_t s_gid;			/* GID of current daemon */
-	int s_fg;			/* Run in foreground */
-	int s_drv_fd;			/* Handle for SMB kernel driver */
-	int s_shutdown_flag;		/* Fields for shutdown control */
-	int s_sigval;
+	const char	*s_version;	/* smbd version string */
+	const char	*s_pname;	/* basename to use for messages */
+	pid_t		s_pid;		/* process-ID of current daemon */
+	uid_t		s_uid;		/* UID of current daemon */
+	gid_t		s_gid;		/* GID of current daemon */
+	int		s_fg;		/* Run in foreground */
+	int		s_drv_fd;	/* Handle for SMB kernel driver */
+	int		s_shutdown_flag; /* Fields for shutdown control */
+	int		s_sigval;
+	boolean_t	s_kbound;	/* B_TRUE if bound to kernel */
+	int		s_door_lmshr;
+	int		s_door_srv;
+	int		s_door_winpipe;
+	int		s_secmode;	/* Current security mode */
+	smb_kmod_cfg_t	s_kcfg;		/* Current Kernel configuration */
 } smbd_t;
 
 #ifdef __cplusplus
--- a/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c	Mon Apr 14 10:40:32 2008 -0700
@@ -306,10 +306,10 @@
 	char *rbuf = NULL;
 	char *name = NULL;
 	uint32_t status;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	uint16_t sid_type;
-	char strsid[NT_SID_FMTBUF_SIZE];
-	char strres[NT_SID_FMTBUF_SIZE];
+	char strsid[SMB_SID_STRSZ];
+	char strres[SMB_SID_STRSZ];
 
 	*err = SMB_DR_OP_SUCCESS;
 	*rbufsize = 0;
@@ -326,7 +326,7 @@
 	xdr_free(xdr_string, (char *)&name);
 	if (status == NT_STATUS_SUCCESS) {
 		/* pack the SID and its type in a string */
-		nt_sid_format2(sid, strsid);
+		smb_sid_tostr(sid, strsid);
 		(void) snprintf(strres, sizeof (strres), "%d-%s",
 		    sid_type, strsid);
 		free(sid);
@@ -350,7 +350,7 @@
 	char *rbuf = NULL;
 	char *name = NULL;
 	uint32_t status;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	char *strsid;
 
 	*err = SMB_DR_OP_SUCCESS;
@@ -362,7 +362,7 @@
 		return (NULL);
 	}
 
-	sid = nt_sid_strtosid(strsid);
+	sid = smb_sid_fromstr(strsid);
 	status = mlsvc_lookup_sid(sid, &name);
 	free(sid);
 	if (status != NT_STATUS_SUCCESS)
--- a/usr/src/cmd/smbsrv/smbd/smbd_join.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbd/smbd_join.c	Mon Apr 14 10:40:32 2008 -0700
@@ -565,12 +565,9 @@
 		syslog(LOG_ERR, "NETLOGON credential chain establishment"
 		    " failed");
 	} else {
-		if (new_domain) {
+		if (new_domain)
 			(void) smb_config_setstr(SMB_CI_DOMAIN_NAME,
 			    kpasswd_domain);
-			(void) smb_config_setstr(SMB_CI_KPASSWD_DOMAIN,
-			    kpasswd_domain);
-		}
 	}
 
 }
--- a/usr/src/cmd/smbsrv/smbd/smbd_logon.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbd/smbd_logon.c	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -85,6 +85,7 @@
 	adt_session_data_t *ah;
 	adt_event_data_t *event;
 	au_tid_addr_t termid;
+	char sidbuf[SMB_SID_STRSZ];
 	uid_t uid;
 	gid_t gid;
 	char *sid;
@@ -94,20 +95,20 @@
 	if ((token = smb_logon(clnt)) == NULL) {
 		uid = ADT_NO_ATTRIB;
 		gid = ADT_NO_ATTRIB;
-		sid = strdup(NT_NULL_SIDSTR);
+		sid = NT_NULL_SIDSTR;
 		status = ADT_FAILURE;
 		retval = ADT_FAIL_VALUE_AUTH;
 	} else {
 		uid = token->tkn_user->i_id;
 		gid = token->tkn_primary_grp->i_id;
-		sid = nt_sid_format(token->tkn_user->i_sidattr.sid);
+		smb_sid_tostr(token->tkn_user->i_sidattr.sid, sidbuf);
+		sid = sidbuf;
 		status = ADT_SUCCESS;
 		retval = ADT_SUCCESS;
 	}
 
 	if (adt_start_session(&ah, NULL, 0)) {
 		syslog(LOG_AUTH | LOG_ALERT, "adt_start_session: %m");
-		free(sid);
 		smb_token_destroy(token);
 		return (NULL);
 	}
@@ -116,7 +117,6 @@
 		syslog(LOG_AUTH | LOG_ALERT,
 		    "adt_alloc_event(ADT_smbd_session): %m");
 		(void) adt_end_session(ah);
-		free(sid);
 		smb_token_destroy(token);
 		return (NULL);
 	}
@@ -131,7 +131,6 @@
 		syslog(LOG_AUTH | LOG_ALERT, "adt_set_user: %m");
 		adt_free_event(event);
 		(void) adt_end_session(ah);
-		free(sid);
 		smb_token_destroy(token);
 		return (NULL);
 	}
@@ -144,13 +143,11 @@
 		syslog(LOG_AUTH | LOG_ALERT, "adt_put_event: %m");
 
 	adt_free_event(event);
-	free(sid);
 
 	if (token) {
 		if ((entry = malloc(sizeof (smb_audit_t))) == NULL) {
 			syslog(LOG_ERR, "smbd_user_auth_logon: %m");
 			(void) adt_end_session(ah);
-			free(sid);
 			smb_token_destroy(token);
 			return (NULL);
 		}
--- a/usr/src/cmd/smbsrv/smbd/smbd_main.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbd/smbd_main.c	Mon Apr 14 10:40:32 2008 -0700
@@ -70,7 +70,7 @@
 static int smbd_daemonize_init(void);
 static void smbd_daemonize_fini(int, int);
 
-static int smbd_kernel_bind(int, int, int);
+static int smbd_kernel_bind(void);
 static void smbd_kernel_unbind(void);
 static int smbd_already_running(void);
 
@@ -86,7 +86,6 @@
 static int smbd_localtime_init(void);
 static void *smbd_localtime_monitor(void *arg);
 
-
 static pthread_t localtime_thr;
 
 static int smbd_refresh_init(void);
@@ -108,10 +107,10 @@
 int
 main(int argc, char *argv[])
 {
-	struct sigaction act;
-	sigset_t set;
-	uid_t uid;
-	int pfd = -1;
+	struct sigaction	act;
+	sigset_t		set;
+	uid_t			uid;
+	int			pfd = -1;
 
 	smbd.s_pname = basename(argv[0]);
 	openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
@@ -327,16 +326,12 @@
 static int
 smbd_service_init(void)
 {
-	int		id_winpipe_door;
-	int		id_lmshr_door;
-	int		id_srv_door;
-	int		rc;
-	uint32_t	mode;
-	char		resource_domain[SMB_PI_MAX_DOMAIN];
-	char		fqdn[MAXHOSTNAMELEN];
+	int	rc;
+	char	resource_domain[SMB_PI_MAX_DOMAIN];
+	char	fqdn[MAXHOSTNAMELEN];
+
 	smbd.s_drv_fd = -1;
 
-
 	if ((mkdir(SMB_DBDIR, 0700) < 0) && (errno != EEXIST)) {
 		smbd_report("mkdir %s: %s", SMB_DBDIR, strerror(errno));
 		return (1);
@@ -354,12 +349,14 @@
 
 	(void) oem_language_set("english");
 
-	if (!nt_builtin_init()) {
+	if (!smb_wka_init()) {
 		smbd_report("out of memory");
 		return (1);
 	}
 
-	(void) smb_nicmon_start();
+	if (smb_nicmon_start(SMBD_DEFAULT_INSTANCE_FMRI) != 0)
+		smbd_report("NIC monitoring failed to start");
+
 	if (dns_msgid_init() != 0) {
 		smbd_report("DNS message id initialization failed");
 		return (1);
@@ -386,8 +383,8 @@
 		return (rc);
 	}
 
-	mode = smb_config_get_secmode();
-	if ((rc = nt_domain_init(resource_domain, mode)) != 0) {
+	smbd.s_secmode = smb_config_get_secmode();
+	if ((rc = nt_domain_init(resource_domain, smbd.s_secmode)) != 0) {
 		if (rc == SMB_DOMAIN_NOMACHINE_SID) {
 			smbd_report(
 			    "no machine SID: check idmap configuration");
@@ -401,7 +398,7 @@
 		return (rc);
 	}
 
-	if (mode == SMB_SECMODE_DOMAIN) {
+	if (smbd.s_secmode == SMB_SECMODE_DOMAIN) {
 		if (!smb_match_netlogon_seqnum())
 			smb_set_netlogon_cred();
 		else
@@ -410,13 +407,13 @@
 		(void) lsa_query_primary_domain_info();
 	}
 
-	id_lmshr_door = smb_lmshrd_srv_start();
-	if (id_lmshr_door < 0) {
+	smbd.s_door_lmshr = smb_lmshrd_srv_start();
+	if (smbd.s_door_lmshr < 0) {
 		smbd_report("share initialization failed");
 	}
 
-	id_srv_door = smb_door_srv_start();
-	if (id_srv_door < 0)
+	smbd.s_door_srv = smb_door_srv_start();
+	if (smbd.s_door_srv < 0)
 		return (rc);
 
 	if ((rc = smbd_refresh_init()) != 0)
@@ -427,8 +424,8 @@
 
 	(void) smbd_localtime_init();
 
-	id_winpipe_door = smb_winpipe_doorsvc_start();
-	if (id_winpipe_door < 0) {
+	smbd.s_door_winpipe = smb_winpipe_doorsvc_start();
+	if (smbd.s_door_winpipe < 0) {
 		smbd_report("winpipe initialization failed %s",
 		    strerror(errno));
 		return (rc);
@@ -438,9 +435,11 @@
 
 	(void) smb_pwd_init();
 
-	rc = smbd_kernel_bind(id_lmshr_door, id_srv_door, id_winpipe_door);
-	if (rc != 0)
+	rc = smbd_kernel_bind();
+	if (rc != 0) {
 		smbd_report("kernel bind error: %s", strerror(errno));
+		return (rc);
+	}
 
 	return (lmshare_start());
 }
@@ -454,7 +453,7 @@
 smbd_service_fini(void)
 {
 	smb_winpipe_doorsvc_stop();
-	nt_builtin_fini();
+	smb_wka_fini();
 	smbd_refresh_fini();
 	smbd_kernel_unbind();
 	smb_door_srv_stop();
@@ -479,9 +478,9 @@
 static int
 smbd_refresh_init()
 {
-	pthread_attr_t tattr;
-	pthread_condattr_t cattr;
-	int rc;
+	pthread_attr_t		tattr;
+	pthread_condattr_t	cattr;
+	int			rc;
 
 	(void) pthread_condattr_init(&cattr);
 	(void) pthread_cond_init(&refresh_cond, &cattr);
@@ -493,8 +492,8 @@
 	(void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
 	rc = pthread_create(&refresh_thr, &tattr, smbd_refresh_monitor, 0);
 	(void) pthread_attr_destroy(&tattr);
+
 	return (rc);
-
 }
 
 /*
@@ -522,7 +521,13 @@
 static void *
 smbd_refresh_monitor(void *arg)
 {
-	int dummy = 0;
+	smb_io_t	smb_io;
+	size_t		len;
+	char		*new_dom;
+	int		new_secmod;
+	char		*old_dom;
+	char		fqdn[MAXHOSTNAMELEN];
+	int		rc = 0;
 
 	(void) pthread_mutex_lock(&refresh_mutex);
 	while (pthread_cond_wait(&refresh_cond, &refresh_mutex) == 0) {
@@ -532,9 +537,51 @@
 		 */
 		ads_refresh();
 		smb_ccache_remove(SMB_CCACHE_PATH);
-		smb_nicmon_reconfig();
+
+		if ((rc = smb_getfqdomainname(fqdn, MAXHOSTNAMELEN)) != 0)
+			smbd_report("failed to get fully qualified domainname");
+
+		if (rc == 0)
+			/* Clear rev zone before creating if list */
+			if (dyndns_clear_rev_zone(fqdn) != 0)
+				smbd_report("failed to clear DNS reverse "
+				    "lookup zone");
+
+		/* re-initialize NIC table */
+		if (smb_nic_init() != 0)
+			smbd_report("failed to get NIC information");
+
+		smb_netbios_name_reconfig();
+		smb_browser_reconfig();
+
+		if (rc == 0)
+			if (dyndns_update(fqdn, B_FALSE) != 0)
+				smbd_report("failed to update dynamic DNS");
+
 		smb_set_netlogon_cred();
-		if (ioctl(smbd.s_drv_fd, SMB_IOC_CONFIG, &dummy) < 0) {
+
+		smb_load_kconfig(&smb_io.sio_data.cfg);
+		new_dom = smb_io.sio_data.cfg.skc_resource_domain;
+		old_dom = smbd.s_kcfg.skc_resource_domain;
+		len = strlen(old_dom);
+		new_secmod = smb_config_get_secmode();
+		if ((len != strlen(new_dom)) ||
+		    (strncasecmp(new_dom, old_dom, len)) ||
+		    (new_secmod != smbd.s_secmode) ||
+		    (smbd.s_drv_fd == -1)) {
+			/*
+			 * The active sessions have to be disconnected.
+			 */
+			smbd_kernel_unbind();
+			if (smbd_kernel_bind()) {
+				smbd_report("kernel bind error: %s",
+				    strerror(errno));
+			}
+			continue;
+		}
+
+		bcopy(&smb_io.sio_data.cfg, &smbd.s_kcfg, sizeof (smbd.s_kcfg));
+		if (ioctl(smbd.s_drv_fd, SMB_IOC_CONFIG, &smb_io) < 0) {
 			smbd_report("configuration update ioctl: %s",
 			    strerror(errno));
 		}
@@ -573,9 +620,11 @@
 
 /*
  * smbd_kernel_bind
+ *
+ * This function open the smbsrv device and start the kernel service.
  */
 static int
-smbd_kernel_bind(int id_lmshr_door, int id_srv_door, int id_winpipe_door)
+smbd_kernel_bind(void)
 {
 	smb_io_t	smb_io;
 	int		rc;
@@ -590,7 +639,8 @@
 		smbd.s_drv_fd = -1;
 		return (errno);
 	}
-	smb_load_kconfig(&smb_io.sio_data.cfg);
+	smb_load_kconfig(&smbd.s_kcfg);
+	bcopy(&smbd.s_kcfg, &smb_io.sio_data.cfg, sizeof (smb_io.sio_data.cfg));
 	if (ioctl(smbd.s_drv_fd, SMB_IOC_CONFIG, &smb_io) < 0) {
 		(void) close(smbd.s_drv_fd);
 		smbd.s_drv_fd = -1;
@@ -602,9 +652,9 @@
 		smbd.s_drv_fd = -1;
 		return (errno);
 	}
-	smb_io.sio_data.start.winpipe = id_winpipe_door;
-	smb_io.sio_data.start.lmshrd = id_lmshr_door;
-	smb_io.sio_data.start.udoor = id_srv_door;
+	smb_io.sio_data.start.winpipe = smbd.s_door_winpipe;
+	smb_io.sio_data.start.lmshrd = smbd.s_door_lmshr;
+	smb_io.sio_data.start.udoor = smbd.s_door_srv;
 	if (ioctl(smbd.s_drv_fd, SMB_IOC_START, &smb_io) < 0) {
 		(void) close(smbd.s_drv_fd);
 		smbd.s_drv_fd = -1;
@@ -615,8 +665,20 @@
 	if (rc == 0) {
 		rc = pthread_create(&tcp_listener, NULL, smbd_tcp_listener,
 		    NULL);
-		if (rc == 0)
+		if (rc == 0) {
+			smbd.s_kbound = B_TRUE;
 			return (0);
+		}
+	}
+
+	rc = pthread_create(&nbt_listener, NULL, smbd_nbt_listener, NULL);
+	if (rc == 0) {
+		rc = pthread_create(&tcp_listener, NULL, smbd_tcp_listener,
+		    NULL);
+		if (rc == 0) {
+			smbd.s_kbound = B_TRUE;
+			return (0);
+		}
 	}
 	(void) close(smbd.s_drv_fd);
 	smbd.s_drv_fd = -1;
@@ -632,6 +694,7 @@
 	if (smbd.s_drv_fd != -1) {
 		(void) close(smbd.s_drv_fd);
 		smbd.s_drv_fd = -1;
+		smbd.s_kbound = B_FALSE;
 	}
 }
 
--- a/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c	Mon Apr 14 10:40:32 2008 -0700
@@ -39,7 +39,6 @@
 #include <pthread.h>
 
 #include <smbsrv/libsmb.h>
-#include <smbsrv/ntsid.h>
 #include <smbsrv/mlsvc.h>
 #include <smbsrv/mlsvc_util.h>
 #include <smbsrv/smb_winpipe.h>
--- a/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c	Mon Apr 14 10:25:34 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*
- * This is the SMB NIC monitoring module.
- */
-#include <sys/types.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <net/if.h>
-#include <net/route.h>
-#include <sys/sockio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <syslog.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbns.h>
-
-static pthread_t smb_nicmon_thread;
-
-static void smb_nicmon_setup_rtsock(int, int *);
-static int smb_nicmon_needscan(int);
-static void *smb_nicmon_daemon(void *);
-static int smb_nicmon_setup_eventpipe(int *, int *);
-
-/* Use this to stop monitoring */
-static int eventpipe_write = -1;
-
-/*
- * Start the nic monitor thread.
- */
-int
-smb_nicmon_start(void)
-{
-	int rc = 0;
-
-	if ((rc = smb_nic_init()) != 0) {
-		syslog(LOG_ERR, "NIC monitor failed to initialize (%s)",
-		    strerror(errno));
-		return (rc);
-	}
-
-	rc = pthread_create(&smb_nicmon_thread, NULL, smb_nicmon_daemon, 0);
-	if (rc != 0) {
-		syslog(LOG_ERR, "NIC monitor failed to start (%s)",
-		    strerror(errno));
-		return (rc);
-	}
-
-	return (rc);
-}
-
-/*
- * Stop the nic monitor.
- */
-void
-smb_nicmon_stop(void)
-{
-	uchar_t buf = 1;
-
-	if (eventpipe_write < 0)
-		return;
-
-	(void) write(eventpipe_write, &buf, sizeof (buf));
-	smb_nic_fini();
-}
-
-/*
- * Call this to do stuff after ifs changed.
- */
-void
-smb_nicmon_reconfig(void)
-{
-	char fqdn[MAXHOSTNAMELEN];
-	boolean_t ddns_enabled;
-
-	ddns_enabled = smb_config_getbool(SMB_CI_DYNDNS_ENABLE);
-	(void) smb_getfqdomainname(fqdn, MAXHOSTNAMELEN);
-
-	/* Clear rev zone before creating if list */
-	if (ddns_enabled) {
-		if (*fqdn != '\0' && dyndns_clear_rev_zone(fqdn) != 0) {
-			syslog(LOG_ERR, "smb_nicmon_daemon: "
-			    "failed to clear DNS reverse lookup zone");
-		}
-	}
-
-	/* re-initialize NIC table */
-	if (smb_nic_init() != 0)
-		syslog(LOG_ERR, "smb_nicmon_daemon: "
-		    "failed to get NIC information");
-
-	smb_netbios_name_reconfig();
-	smb_browser_reconfig();
-
-	if (ddns_enabled) {
-		if (*fqdn != '\0' && dyndns_update(fqdn, B_FALSE) != 0) {
-			syslog(LOG_ERR, "smb_nicmon_daemon: "
-			    "failed to update dynamic DNS");
-		}
-	}
-}
-
-/*
- * Setup routing socket for getting RTM messages.
- */
-static void
-smb_nicmon_setup_rtsock(int af, int *s)
-{
-	int flags;
-
-	*s = socket(PF_ROUTE, SOCK_RAW, af);
-	if (*s == -1) {
-		syslog(LOG_ERR, "smb_nicmon_daemon: failed to "
-		    "create routing socket");
-		return;
-	}
-	if ((flags = fcntl(*s, F_GETFL, 0)) < 0) {
-		syslog(LOG_ERR, "smb_nicmon_daemon: "
-		    "failed to fcntl F_GETFL");
-		(void) close(*s);
-		*s = -1;
-		return;
-	}
-	if ((fcntl(*s, F_SETFL, flags | O_NONBLOCK)) < 0) {
-		syslog(LOG_ERR, "smb_nicmon_daemon: "
-		    "failed to fcntl F_SETFL");
-		(void) close(*s);
-		*s = -1;
-		return;
-	}
-}
-
-static int
-smb_nicmon_needscan(int sock)
-{
-	int	nbytes;
-	int64_t msg[2048 / 8];
-	struct rt_msghdr *rtm;
-	int need_if_scan = 0;
-
-	/* Read as many messages as possible and try to empty the sockets */
-	for (;;) {
-		nbytes = read(sock, msg, sizeof (msg));
-		if (nbytes <= 0) {
-			break;
-		}
-		rtm = (struct rt_msghdr *)msg;
-		if (rtm->rtm_version != RTM_VERSION) {
-			continue;
-		}
-		if (nbytes < rtm->rtm_msglen) {
-			syslog(LOG_DEBUG, "smb_nicmon_daemon: short read: %d "
-			    "of %d", nbytes, rtm->rtm_msglen);
-			continue;
-		}
-
-		switch (rtm->rtm_type) {
-		case RTM_NEWADDR:
-		case RTM_DELADDR:
-		case RTM_IFINFO:
-			need_if_scan = 1;
-			break;
-		default:
-			break;
-		}
-	}
-
-	return (need_if_scan);
-}
-
-/*
- * Create pipe for signal delivery and set up signal handlers.
- */
-static int
-smb_nicmon_setup_eventpipe(int *read_pipe, int *write_pipe)
-{
-	int fds[2];
-
-	if ((pipe(fds)) < 0) {
-		syslog(LOG_ERR, "smb_nicmon_daemon: failed to open pipe");
-		return (1);
-	}
-	*read_pipe = fds[0];
-	*write_pipe = fds[1];
-	return (0);
-}
-
-/*ARGSUSED*/
-static void *
-smb_nicmon_daemon(void *args)
-{
-	struct pollfd pollfds[2];
-	int pollfd_num = 2;
-	int i, nic_changed;
-	/* AF_INET routing socket add AF_INET6 when we support IPv6 */
-	static int rtsock_v4;
-	static int eventpipe_read = -1;
-
-	/*
-	 * Create the global routing socket.  We use this to
-	 * monitor changes in NIC interfaces. We are only interested
-	 * in new inerface addition/deletion and change in UP/DOWN status.
-	 */
-	smb_nicmon_setup_rtsock(AF_INET, &rtsock_v4);
-	if (rtsock_v4 == -1) {
-		syslog(LOG_ERR, "smb_nicmon_daemon: "
-		    "cannot open routing socket");
-		return (NULL);
-	}
-
-	if (smb_nicmon_setup_eventpipe(&eventpipe_read, &eventpipe_write)
-	    != 0) {
-		syslog(LOG_ERR, "smb_nicmon_daemon: cannot open event pipes");
-		return (NULL);
-	}
-
-	/*
-	 * Keep listening for activity on any of the sockets.
-	 */
-	for (;;) {
-		nic_changed = 0;
-		pollfds[0].fd = rtsock_v4;
-		pollfds[0].events = POLLIN;
-		pollfds[1].fd = eventpipe_read;
-		pollfds[1].events = POLLIN;
-		if (poll(pollfds, pollfd_num, -1) < 0) {
-			if (errno == EINTR)
-				continue;
-			syslog(LOG_ERR, "smb_nicmon_daemon: "
-			    "poll failed with errno %d", errno);
-			break;
-		}
-		for (i = 0; i < pollfd_num; i++) {
-			if ((pollfds[i].fd < 0) ||
-			    !(pollfds[i].revents & POLLIN))
-				continue;
-			if (pollfds[i].fd == rtsock_v4)
-				nic_changed = smb_nicmon_needscan(rtsock_v4);
-			if (pollfds[i].fd == eventpipe_read)
-				goto done;
-		}
-
-		/*
-		 * If anything changed do refresh our
-		 * nic list and other configs.
-		 */
-		if (nic_changed)
-			smb_nicmon_reconfig();
-	}
-done:
-	/* Close sockets */
-	(void) close(rtsock_v4);
-	(void) close(eventpipe_read);
-	(void) close(eventpipe_write);
-	eventpipe_write = -1;
-	return (NULL);
-}
--- a/usr/src/cmd/smbsrv/smbstat/smbstat.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/cmd/smbsrv/smbstat/smbstat.c	Mon Apr 14 10:40:32 2008 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -39,17 +39,18 @@
 #include <utility.h>
 #include <libintl.h>
 #include <zone.h>
+#include <smbsrv/smb_kstat.h>
 
-static kstat_ctl_t *kc;		/* libkstat cookie */
-static kstat_t *smb_info;
-static kstat_t *smb_dispatch;
-static kstat_t *ksmb_kstat;
+static kstat_ctl_t	*kc;		/* libkstat cookie */
+static kstat_t		*smb_server;
+static kstat_t		*smb_cmds;
 
 static int get_smbinfo_stat(void);
 static int get_smbdispatch_stat(void);
-static void smbstat_setup(void);
-static void smbstat_smb_info_print();
-static void smbstat_smb_dispatch_print();
+static void smbstat_init(void);
+static void smbstat_fini(void);
+static void smbstat_smb_server_print();
+static void smbstat_smb_cmds_print();
 static void smbstat_print(const char *, kstat_t *, int);
 static int smbstat_width(kstat_t *, int);
 static void smbstat_fail(int, char *, ...);
@@ -62,8 +63,8 @@
 main(int argc, char *argv[])
 {
 	int c;
-	int iflag = 0;		/* smb_info stats */
-	int dflag = 0;		/* smb_dispatch_all stats */
+	int iflag = 0;		/* smb_server stats */
+	int dflag = 0;		/* smb_cmds_all stats */
 
 	if (getzoneid() != GLOBAL_ZONEID) {
 		(void) fprintf(stderr,
@@ -97,19 +98,18 @@
 		smbstat_usage();
 	}
 
-	smbstat_setup();
+	smbstat_init();
 
 	if (iflag) {
-		smbstat_smb_info_print();
+		smbstat_smb_server_print();
 	} else if (dflag) {
-		smbstat_smb_dispatch_print();
+		smbstat_smb_cmds_print();
 	} else {
-		smbstat_smb_info_print();
-		smbstat_smb_dispatch_print();
+		smbstat_smb_server_print();
+		smbstat_smb_cmds_print();
 	}
 
-	(void) kstat_close(kc);
-	free(ksmb_kstat);
+	smbstat_fini();
 	return (0);
 }
 
@@ -117,31 +117,53 @@
 static int
 get_smbinfo_stat(void)
 {
-	(void) smbstat_kstat_read(kc, smb_info, NULL);
-	return (smbstat_width(smb_info, 0));
+	(void) smbstat_kstat_read(kc, smb_server, NULL);
+	return (smbstat_width(smb_server, 0));
 }
 
 static int
 get_smbdispatch_stat(void)
 {
-	(void) smbstat_kstat_read(kc, smb_dispatch, NULL);
-	return (smbstat_width(smb_dispatch, 0));
+	(void) smbstat_kstat_read(kc, smb_cmds, NULL);
+	return (smbstat_width(smb_cmds, 0));
 }
 
 static void
-smbstat_smb_info_print()
+smbstat_smb_server_print()
 {
-	int field_width;
+	int	field_width;
+	int	i, j, nreq, ncolumns;
+	char	fixlen[128];
+	kstat_named_t *knp;
 
 	field_width = get_smbinfo_stat();
 	if (field_width == 0)
 		return;
 
-	smbstat_print(gettext("\nSMB Info:\n"), smb_info, field_width);
+	(void) printf("%s\n", "\nSMB Info:\n");
+	ncolumns = (MAX_COLUMNS -1)/field_width;
+
+	knp = KSTAT_NAMED_PTR(smb_server);
+	nreq = smb_server->ks_ndata;
+
+	for (i = 0; i < nreq; i += ncolumns) {
+		/* prints out the titles of the columns */
+		for (j = i; j < MIN(i + ncolumns, nreq); j++) {
+			(void) printf("%-*s", field_width, knp[j].name);
+		}
+		(void) printf("\n");
+		/* prints out the stat numbers */
+		for (j = i; j < MIN(i + ncolumns, nreq); j++) {
+			(void) sprintf(fixlen, "%" PRIu32 " ",
+			    knp[j].value.ui32);
+			(void) printf("%-*s", field_width, fixlen);
+		}
+		(void) printf("\n");
+	}
 }
 
 static void
-smbstat_smb_dispatch_print()
+smbstat_smb_cmds_print()
 {
 	int field_width;
 
@@ -150,27 +172,35 @@
 		return;
 
 	smbstat_print(gettext("\nAll dispatched SMB requests statistics:\n"),
-	    smb_dispatch, field_width);
+	    smb_cmds, field_width);
 }
 
 static void
-smbstat_setup(void)
+smbstat_init(void)
 {
+	char	smbsrv_name[KSTAT_STRLEN];
+
+	(void) snprintf(smbsrv_name, sizeof (smbsrv_name), "%s%d",
+	    SMBSRV_KSTAT_NAME, getzoneid());
+
 	if ((kc = kstat_open()) == NULL)
 		smbstat_fail(1, gettext("kstat_open(): can't open /dev/kstat"));
 
-	if ((ksmb_kstat = malloc(sizeof (kstat_t))) == NULL) {
-		(void) kstat_close(kc);
-		smbstat_fail(1, gettext("Out of memory"));
-	}
+	smb_server = kstat_lookup(kc, SMBSRV_KSTAT_MODULE, 0, smbsrv_name);
+	smb_cmds = kstat_lookup(kc, SMBSRV_KSTAT_MODULE, 0,
+	    SMBSRV_KSTAT_NAME_CMDS);
 
-	smb_info = kstat_lookup(kc, "smb", 0, "smb_info");
-	smb_dispatch = kstat_lookup(kc, "smb", 0, "smb_dispatch_all");
-	if ((smb_info == NULL) || (smb_dispatch == NULL))
+	if ((smb_server == NULL) || (smb_cmds == NULL))
 		smbstat_fail(0, gettext("kstat lookups failed for smb. "
 		    "Your kernel module may not be loaded\n"));
 }
 
+static void
+smbstat_fini(void)
+{
+	(void) kstat_close(kc);
+}
+
 static int
 smbstat_width(kstat_t *req, int field_width)
 {
--- a/usr/src/common/smbsrv/smb_sid.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/common/smbsrv/smb_sid.c	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -40,419 +40,274 @@
 #include <sys/sunddi.h>
 #endif /* _KERNEL */
 
-#include <smbsrv/alloc.h>
-#include <smbsrv/ntsid.h>
-#include <smbsrv/ntstatus.h>
-#include <smbsrv/smbinfo.h>
+#include <smbsrv/smb_sid.h>
 
+static smb_sid_t *smb_sid_alloc(size_t);
 
 /*
- * nt_sid_is_valid
+ * smb_sid_isvalid
  *
- * Check that a sid is valid. The checking is minimal: check the pointer
- * is valid and that the revision and sub-authority count is legal.
- * Returns 1 if the sid appears to be valid. Otherwise 0.
+ * Performs a minimal SID validation.
  */
-int
-nt_sid_is_valid(nt_sid_t *sid)
+boolean_t
+smb_sid_isvalid(smb_sid_t *sid)
 {
-	if (sid == 0)
-		return (0);
+	if (sid == NULL)
+		return (B_FALSE);
 
-	return (sid->Revision == NT_SID_REVISION &&
-	    sid->SubAuthCount < NT_SID_SUBAUTH_MAX) ? 1 : 0;
+	return ((sid->sid_revision == NT_SID_REVISION) &&
+	    (sid->sid_subauthcnt < NT_SID_SUBAUTH_MAX));
 }
 
-
 /*
- * nt_sid_length
+ * smb_sid_len
  *
  * Returns the number of bytes required to hold the sid.
  */
 int
-nt_sid_length(nt_sid_t *sid)
+smb_sid_len(smb_sid_t *sid)
 {
-	if (sid == 0)
+	if (sid == NULL)
 		return (0);
 
-	return (sizeof (nt_sid_t) - sizeof (DWORD)
-	    + (sid->SubAuthCount * sizeof (DWORD)));
+	return (sizeof (smb_sid_t) - sizeof (uint32_t)
+	    + (sid->sid_subauthcnt * sizeof (uint32_t)));
 }
 
-
 /*
- * nt_sid_dup
+ * smb_sid_dup
  *
- * Make a duplicate of the specified sid. The memory for the new sid is
- * allocated using malloc so the caller should call free when it is no
- * longer required. A pointer to the new sid is returned.
+ * Make a duplicate of the specified sid. The memory for the new sid
+ * should be freed by calling smb_sid_free().
+ * A pointer to the new sid is returned.
  */
-nt_sid_t *
-nt_sid_dup(nt_sid_t *sid)
+smb_sid_t *
+smb_sid_dup(smb_sid_t *sid)
 {
-	nt_sid_t *new_sid;
+	smb_sid_t *new_sid;
 	int size;
-	int i;
 
-	if (sid == 0)
-		return (0);
-
-	size = sizeof (nt_sid_t)
-	    + (sid->SubAuthCount * sizeof (DWORD))
-	    + sizeof (DWORD);
+	if (sid == NULL)
+		return (NULL);
 
-	if ((new_sid = MEM_MALLOC("libnt", size)) == 0)
-		return (0);
+	size = smb_sid_len(sid);
+	if ((new_sid = smb_sid_alloc(size)) == NULL)
+		return (NULL);
 
-	(void) memcpy(new_sid, sid, sizeof (nt_sid_t));
-
-	for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i)
-		new_sid->SubAuthority[i] = sid->SubAuthority[i];
-
+	bcopy(sid, new_sid, size);
 	return (new_sid);
 }
 
 
 /*
- * nt_sid_splice
+ * smb_sid_splice
  *
- * Make a full user sid from the domain sid and the user relative id
- * (rid). The memory for the new sid is allocated using malloc so the
- * caller should call free when it is no longer required. A pointer
- * to the new sid is returned.
+ * Make a full sid from a domain sid and a relative id (rid).
+ * The memory for the result sid should be freed by calling
+ * smb_sid_free(). A pointer to the new sid is returned.
  */
-nt_sid_t *
-nt_sid_splice(nt_sid_t *domain_sid, DWORD rid)
+smb_sid_t *
+smb_sid_splice(smb_sid_t *domain_sid, uint32_t rid)
 {
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	int size;
-	int i;
 
-	if (domain_sid == 0)
-		return (0);
-
-	size = sizeof (nt_sid_t)
-	    + (domain_sid->SubAuthCount * sizeof (DWORD))
-	    + sizeof (DWORD);
+	if (domain_sid == NULL)
+		return (NULL);
 
-	if ((sid = MEM_MALLOC("libnt", size)) == 0)
-		return (0);
-
-	(void) memcpy(sid, domain_sid, sizeof (nt_sid_t));
+	size = smb_sid_len(domain_sid);
+	if ((sid = smb_sid_alloc(size + sizeof (rid))) == NULL)
+		return (NULL);
 
-	for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i)
-		sid->SubAuthority[i] = domain_sid->SubAuthority[i];
+	bcopy(domain_sid, sid, size);
 
-	sid->SubAuthority[i] = rid;
-	++sid->SubAuthCount;
+	sid->sid_subauth[domain_sid->sid_subauthcnt] = rid;
+	++sid->sid_subauthcnt;
+
 	return (sid);
 }
 
-
 /*
- * nt_sid_get_rid
+ * smb_sid_getrid
  *
- * Return the Relative Id (RID) from the specified SID. It is the
+ * Return the Relative Id (RID) of the specified SID. It is the
  * caller's responsibility to ensure that this is an appropriate SID.
  * All we do here is return the last sub-authority from the SID.
  */
 int
-nt_sid_get_rid(nt_sid_t *sid, DWORD *rid)
+smb_sid_getrid(smb_sid_t *sid, uint32_t *rid)
 {
-	if (!nt_sid_is_valid(sid))
+	if (!smb_sid_isvalid(sid) || (rid == NULL) ||
+	    (sid->sid_subauthcnt == 0))
 		return (-1);
 
-	if (sid->SubAuthCount == 0) {
+	*rid = sid->sid_subauth[sid->sid_subauthcnt - 1];
+	return (0);
+}
+
+/*
+ * smb_sid_split
+ *
+ * Take a full sid and split it into a domain sid and a relative id (rid).
+ *
+ * IMPORTANT: The original sid is modified in place - use smb_sid_dup before
+ * calling this function to preserve the original SID. Be careful if you're
+ * using this function in kernel code, after calling this function 'sid'
+ * cannot be passed to smb_sid_free() because the size won't match the original
+ * allocated size. Use smb_sid_ksplit() instead.
+ */
+int
+smb_sid_split(smb_sid_t *sid, uint32_t *rid)
+{
+	if (!smb_sid_isvalid(sid) || (sid->sid_subauthcnt == 0))
 		return (-1);
-	}
 
+	--sid->sid_subauthcnt;
 	if (rid)
-		*rid = sid->SubAuthority[sid->SubAuthCount - 1];
+		*rid = sid->sid_subauth[sid->sid_subauthcnt];
 	return (0);
 }
 
-
 /*
- * nt_sid_split
+ * smb_sid_splitstr
  *
- * Take a full user sid and split it into the domain sid and the user
- * relative id (rid). The original sid is modified in place - use
- * nt_sid_dup before calling this function to preserve the original SID.
+ * Takes a full sid in string form and split it into a domain sid and a
+ * relative id (rid).
+ *
+ * IMPORTANT: The original sid is modified in place. This function assumes
+ * given SID is in valid string format.
  */
 int
-nt_sid_split(nt_sid_t *sid, DWORD *rid)
+smb_sid_splitstr(char *strsid, uint32_t *rid)
 {
-	if (!nt_sid_is_valid(sid)) {
+	char *p;
+
+	if ((p = strrchr(strsid, '-')) == NULL)
 		return (-1);
+
+	*p++ = '\0';
+	if (rid) {
+#ifdef _KERNEL
+		unsigned long sua = 0;
+		(void) ddi_strtoul(p, NULL, 10, &sua);
+		*rid = (uint32_t)sua;
+#else
+		*rid = strtoul(p, NULL, 10);
+#endif
 	}
 
-	if (sid->SubAuthCount == 0) {
-		return (-1);
-	}
-
-	--sid->SubAuthCount;
-	if (rid)
-		*rid = sid->SubAuthority[sid->SubAuthCount];
 	return (0);
 }
 
-
 /*
- * nt_sid_gen_null_sid
- *
- * This function allocates a SID structure and initializes it as the
- * well-known Null SID (S-1-0-0). A pointer to the SID is returned.
- * As the memory for this structure is obtained via malloc, it is the
- * caller's responsibility to free the memory when it is no longer
- * required. If malloc fails, a null pointer is returned.
- */
-nt_sid_t *
-nt_sid_gen_null_sid(void)
-{
-	nt_sid_t *sid;
-	int size;
-
-	size = sizeof (nt_sid_t) + sizeof (DWORD);
-
-	if ((sid = MEM_MALLOC("libnt", size)) == 0) {
-		return (0);
-	}
-
-	sid->Revision = 1;
-	sid->SubAuthCount = 1;
-	return (sid);
-}
-
-
-/*
- * nt_sid_is_equal
+ * smb_sid_cmp
  *
  * Compare two SIDs and return a boolean result. The checks are ordered
  * such that components that are more likely to differ are checked
  * first. For example, after checking that the SIDs contain the same
- * SubAuthCount, we check the sub-authorities in reverse order because
+ * sid_subauthcnt, we check the sub-authorities in reverse order because
  * the RID is the most likely differentiator between two SIDs, i.e.
  * they are probably going to be in the same domain.
- *
- * Returns 1 if the SIDs are equal. Otherwise returns 0.
  */
-int
-nt_sid_is_equal(nt_sid_t *sid1, nt_sid_t *sid2)
+boolean_t
+smb_sid_cmp(smb_sid_t *sid1, smb_sid_t *sid2)
 {
 	int i;
 
-	if (sid1 == 0 || sid2 == 0)
-		return (0);
+	if (sid1 == NULL || sid2 == NULL)
+		return (B_FALSE);
 
-	if (sid1->SubAuthCount != sid2->SubAuthCount ||
-	    sid1->Revision != sid2->Revision)
-		return (0);
+	if (sid1->sid_subauthcnt != sid2->sid_subauthcnt ||
+	    sid1->sid_revision != sid2->sid_revision)
+		return (B_FALSE);
 
-	for (i = sid1->SubAuthCount - 1; i >= 0; --i)
-		if (sid1->SubAuthority[i] != sid2->SubAuthority[i])
-			return (0);
+	for (i = sid1->sid_subauthcnt - 1; i >= 0; --i)
+		if (sid1->sid_subauth[i] != sid2->sid_subauth[i])
+			return (B_FALSE);
 
-	if (bcmp(&sid1->Authority, &sid2->Authority, NT_SID_AUTH_MAX))
-		return (0);
+	if (bcmp(&sid1->sid_authority, &sid2->sid_authority, NT_SID_AUTH_MAX))
+		return (B_FALSE);
 
-	return (1);
+	return (B_TRUE);
 }
 
 /*
- * nt_sid_is_indomain
+ * smb_sid_indomain
  *
  * Check if given SID is in given domain.
- * Returns 1 on success. Otherwise returns 0.
  */
-int
-nt_sid_is_indomain(nt_sid_t *domain_sid, nt_sid_t *sid)
+boolean_t
+smb_sid_indomain(smb_sid_t *domain_sid, smb_sid_t *sid)
 {
 	int i;
 
-	if (sid == 0 || domain_sid == 0) {
-		return (0);
-	}
+	if (sid == NULL || domain_sid == NULL)
+		return (B_FALSE);
 
-	if (domain_sid->Revision != sid->Revision ||
-	    sid->SubAuthCount < domain_sid->SubAuthCount)
-		return (0);
+	if (domain_sid->sid_revision != sid->sid_revision ||
+	    sid->sid_subauthcnt < domain_sid->sid_subauthcnt)
+		return (B_FALSE);
 
-	for (i = domain_sid->SubAuthCount - 1; i >= 0; --i)
-		if (domain_sid->SubAuthority[i] != sid->SubAuthority[i])
-			return (0);
+	for (i = domain_sid->sid_subauthcnt - 1; i >= 0; --i)
+		if (domain_sid->sid_subauth[i] != sid->sid_subauth[i])
+			return (B_FALSE);
 
-	if (bcmp(&domain_sid->Authority, &sid->Authority, NT_SID_AUTH_MAX))
-		return (0);
+	if (bcmp(&domain_sid->sid_authority, &sid->sid_authority,
+	    NT_SID_AUTH_MAX))
+		return (B_FALSE);
 
-	return (1);
+	return (B_TRUE);
 }
 
 #ifndef _KERNEL
 /*
- * nt_sid_is_local
+ * smb_sid_islocal
  *
- * Check a SID to see if it belongs to the local domain. This is almost
- * the same as checking that two SIDs are equal except that we don't
- * care if the specified SID contains extra sub-authorities. We're only
- * interested in the domain part.
- *
- * Returns 1 if the SIDs are equal. Otherwise returns 0.
+ * Check a SID to see if it belongs to the local domain.
  */
-int
-nt_sid_is_local(nt_sid_t *sid)
+boolean_t
+smb_sid_islocal(smb_sid_t *sid)
 {
-	nt_sid_t *local_sid;
-
-	local_sid = nt_domain_local_sid();
-	return (nt_sid_is_indomain(local_sid, sid));
-}
-
-/*
- * nt_sid_is_builtin
- *
- * Check a SID to see if it belongs to the builtin domain.
- * Returns 1 if the SID is a builtin SID. Otherwise returns 0.
- */
-int
-nt_sid_is_builtin(nt_sid_t *sid)
-{
-	nt_domain_t *domain;
-
-	domain = nt_domain_lookupbytype(NT_DOMAIN_BUILTIN);
-	if (domain == 0)
-		return (0);
-	return (nt_sid_is_indomain(domain->sid, sid));
+	return (smb_sid_indomain(nt_domain_local_sid(), sid));
 }
 #endif /* _KERNEL */
 
 /*
- * nt_sid_is_domain_equal
- *
- * Compare two SIDs's domain and return a boolean result.
+ * smb_sid_tostr
  *
- * Returns 1 if the domain SID are the same. Otherwise returns 0.
- */
-int
-nt_sid_is_domain_equal(nt_sid_t *pSid1, nt_sid_t *pSid2)
-{
-	int		i, n;
-
-	if (pSid1->Revision != pSid2->Revision)
-		return (0);
-
-	if (pSid1->SubAuthCount != pSid2->SubAuthCount)
-		return (0);
-
-	if (bcmp(pSid1->Authority, pSid2->Authority, NT_SID_AUTH_MAX) != 0)
-		return (0);
-
-	n = pSid1->SubAuthCount;
-
-	n -= 1;		/* don't compare last SubAuthority[] (aka RID) */
-
-	for (i = 0; i < n; i++)
-		if (pSid1->SubAuthority[i] != pSid2->SubAuthority[i])
-			return (0);
-
-	return (1);
-}
-
-/*
- * nt_sid_logf
- *
- * Format a sid and write it to the system log. See nt_sid_format
- * for format information.
+ * Fill in the passed buffer with the string form of the given
+ * binary sid.
  */
 void
-nt_sid_logf(nt_sid_t *sid)
+smb_sid_tostr(smb_sid_t *sid, char *strsid)
 {
-	char *s;
+	char *p = strsid;
+	int i;
 
-	if ((s = nt_sid_format(sid)) == 0)
+	if (sid == NULL || strsid == NULL)
 		return;
 
-	MEM_FREE("libnt", s);
-}
-
-
-/*
- * nt_sid_format
- *
- * Format a sid and return it as a string. The memory for the string is
- * allocated using malloc so the caller should call free when it is no
- * longer required. A pointer to the string is returned.
- */
-char *
-nt_sid_format(nt_sid_t *sid)
-{
-	int i;
-	char *fmtbuf;
-	char *p;
-
-	if (sid == 0)
-		return (0);
-
-	if ((fmtbuf = MEM_MALLOC("libnt", NT_SID_FMTBUF_SIZE)) == 0)
-		return (0);
-
-	p = fmtbuf;
-	(void) sprintf(p, "S-%d-", sid->Revision);
+	(void) sprintf(p, "S-%d-", sid->sid_revision);
 	while (*p)
-		++p;
+		p++;
 
 	for (i = 0; i < NT_SID_AUTH_MAX; ++i) {
-		if (sid->Authority[i] != 0 || i == NT_SID_AUTH_MAX - 1)	{
-			(void) sprintf(p, "%d", sid->Authority[i]);
+		if (sid->sid_authority[i] != 0 || i == NT_SID_AUTH_MAX - 1) {
+			(void) sprintf(p, "%d", sid->sid_authority[i]);
 			while (*p)
-				++p;
+				p++;
 		}
 	}
 
-	for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i) {
-		(void) sprintf(p, "-%u", sid->SubAuthority[i]);
+	for (i = 0; i < sid->sid_subauthcnt && i < NT_SID_SUBAUTH_MAX; ++i) {
+		(void) sprintf(p, "-%u", sid->sid_subauth[i]);
 		while (*p)
-			++p;
-	}
-
-	return (fmtbuf);
-}
-
-/*
- * nt_sid_format2
- *
- * Format a sid and return it in the passed buffer.
- */
-void
-nt_sid_format2(nt_sid_t *sid, char *fmtbuf)
-{
-	int i;
-	char *p;
-
-	if (sid == 0 || fmtbuf == 0)
-		return;
-
-	p = fmtbuf;
-	(void) sprintf(p, "S-%d-", sid->Revision);
-	while (*p)
-		++p;
-
-	for (i = 0; i < NT_SID_AUTH_MAX; ++i) {
-		if (sid->Authority[i] != 0 || i == NT_SID_AUTH_MAX - 1) {
-			(void) sprintf(p, "%d", sid->Authority[i]);
-			while (*p)
-				++p;
-		}
-	}
-
-	for (i = 0; i < sid->SubAuthCount && i < NT_SID_SUBAUTH_MAX; ++i) {
-		(void) sprintf(p, "-%u", sid->SubAuthority[i]);
-		while (*p)
-			++p;
+			p++;
 	}
 }
 
 /*
- * nt_sid_strtosid
+ * smb_sid_fromstr
  *
  * Converts a SID in string form to a SID structure. There are lots of
  * simplifying assumptions in here. The memory for the SID is allocated
@@ -464,80 +319,108 @@
  *
  * On success, a pointer to a SID is returned. Otherwise a null pointer
  * is returned.
- *
- * XXX this function may have endian issues
  */
-nt_sid_t *
-nt_sid_strtosid(char *sidstr)
+#ifdef _KERNEL
+smb_sid_t *
+smb_sid_fromstr(char *sidstr)
 {
-	nt_sid_t *sid;
+	smb_sid_t *sid;
+	smb_sid_t *retsid;
 	char *p;
 	int size;
-	BYTE i;
-#ifdef _KERNEL
-	long sua;
-#endif /* _KERNEL */
+	uint8_t i;
+	unsigned long sua;
 
-	if (sidstr == 0) {
-		return (0);
-	}
-
-	if (strncmp(sidstr, "S-1-", 4) != 0) {
-		return (0);
-	}
-
-	size = sizeof (nt_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (DWORD));
+	if (sidstr == NULL)
+		return (NULL);
 
-	if ((sid = MEM_MALLOC("libnt", size)) == 0) {
-		return (0);
-	}
+	if (strncmp(sidstr, "S-1-", 4) != 0)
+		return (NULL);
 
-	bzero(sid, size);
-	sid->Revision = NT_SID_REVISION;
-#ifndef _KERNEL
-	sid->Authority[5] = atoi(&sidstr[4]);
-#else /* _KERNEL */
+	size = sizeof (smb_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (uint32_t));
+	sid = kmem_zalloc(size, KM_SLEEP);
+
+	sid->sid_revision = NT_SID_REVISION;
 	sua = 0;
-	/* XXX Why are we treating sua as a long/unsigned long? */
-	(void) ddi_strtoul(&sidstr[4], 0, 10, (unsigned long *)&sua);
-	sid->Authority[5] = (BYTE)sua;
-#endif /* _KERNEL */
+	(void) ddi_strtoul(&sidstr[4], 0, 10, &sua);
+	sid->sid_authority[5] = (uint8_t)sua;
 
 	for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) {
 		while (*p && *p == '-')
 			++p;
 
 		if (*p < '0' || *p > '9') {
-			MEM_FREE("libnt", sid);
-			return (0);
+			kmem_free(sid, size);
+			return (NULL);
 		}
 
-#ifndef _KERNEL
-		sid->SubAuthority[i] = strtoul(p, 0, 10);
-#else /* _KERNEL */
 		sua = 0;
-		(void) ddi_strtoul(p, 0, 10, (unsigned long *)&sua);
-		sid->SubAuthority[i] = (DWORD)sua;
-#endif /* _KERNEL */
+		(void) ddi_strtoul(p, 0, 10, &sua);
+		sid->sid_subauth[i] = (uint32_t)sua;
 
 		while (*p && *p != '-')
 			++p;
 	}
 
-	sid->SubAuthCount = i;
+	sid->sid_subauthcnt = i;
+	retsid = smb_sid_dup(sid);
+	kmem_free(sid, size);
+
+	return (retsid);
+}
+#else /* _KERNEL */
+smb_sid_t *
+smb_sid_fromstr(char *sidstr)
+{
+	smb_sid_t *sid;
+	char *p;
+	int size;
+	uint8_t i;
+
+	if (sidstr == NULL)
+		return (NULL);
+
+	if (strncmp(sidstr, "S-1-", 4) != 0)
+		return (NULL);
+
+	size = sizeof (smb_sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (uint32_t));
+
+	if ((sid = malloc(size)) == NULL)
+		return (NULL);
+
+	bzero(sid, size);
+	sid->sid_revision = NT_SID_REVISION;
+	sid->sid_authority[5] = atoi(&sidstr[4]);
+
+	for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) {
+		while (*p && *p == '-')
+			++p;
+
+		if (*p < '0' || *p > '9') {
+			free(sid);
+			return (NULL);
+		}
+
+		sid->sid_subauth[i] = strtoul(p, NULL, 10);
+
+		while (*p && *p != '-')
+			++p;
+	}
+
+	sid->sid_subauthcnt = i;
 	return (sid);
 }
-
+#endif /* _KERNEL */
 
 /*
- * nt_sid_name_use
+ * smb_sid_type2str
  *
  * Returns the text name for a SID_NAME_USE value. The SID_NAME_USE
  * provides the context for a SID, i.e. the type of resource to which
  * it refers.
  */
 char *
-nt_sid_name_use(unsigned int snu_id)
+smb_sid_type2str(uint16_t snu_id)
 {
 	static char *snu_name[] = {
 		"SidTypeSidPrefix",
@@ -553,35 +436,31 @@
 
 	if (snu_id < ((sizeof (snu_name)/sizeof (snu_name[0]))))
 		return (snu_name[snu_id]);
-	else {
-		return (snu_name[SidTypeUnknown]);
-	}
+
+	return (snu_name[SidTypeUnknown]);
 }
 
-
-/*
- * nt_sid_copy
- *
- * Copy information of srcsid to dessid. The buffer should be allocated
- * for dessid before passing to this function. The size of buffer for
- * dessid should be specified in the buflen.
- *
- * Returns total bytes of information copied. If there is an error, 0
- * will be returned.
- */
-int
-nt_sid_copy(nt_sid_t *dessid, nt_sid_t *srcsid, unsigned buflen)
+static smb_sid_t *
+smb_sid_alloc(size_t size)
 {
-	unsigned		n_bytes;
-
-	if (!dessid || !srcsid)
-		return (0);
+	smb_sid_t *sid;
+#ifdef _KERNEL
+	sid = kmem_alloc(size, KM_SLEEP);
+#else
+	sid = malloc(size);
+#endif
+	return (sid);
+}
 
-	n_bytes = nt_sid_length(srcsid);
-	if (n_bytes > buflen)
-		return (0);
+void
+smb_sid_free(smb_sid_t *sid)
+{
+#ifdef _KERNEL
+	if (sid == NULL)
+		return;
 
-	bcopy((char *)srcsid, (char *)dessid, n_bytes);
-
-	return (n_bytes);
+	kmem_free(sid, smb_sid_len(sid));
+#else
+	free(sid);
+#endif
 }
--- a/usr/src/common/smbsrv/smb_string.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/common/smbsrv/smb_string.c	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -37,7 +37,6 @@
 #include <string.h>
 #include <strings.h>
 #endif
-#include <smbsrv/alloc.h>
 #include <smbsrv/string.h>
 #include <smbsrv/ctype.h>
 
--- a/usr/src/common/smbsrv/smb_token.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/common/smbsrv/smb_token.c	Mon Apr 14 10:40:32 2008 -0700
@@ -32,185 +32,19 @@
 
 #ifdef _KERNEL
 #include <sys/types.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/ksynch.h>
 #include <sys/cmn_err.h>
-#include <sys/time.h>
 #include <sys/kmem.h>
 #else /* _KERNEL */
 #include <stdlib.h>
 #include <strings.h>
-#include <thread.h>
-#include <synch.h>
 #include <syslog.h>
-#include <time.h>
-#include <arpa/inet.h>
-#include <sys/varargs.h>
-#include <smbsrv/alloc.h>
 #endif /* _KERNEL */
 
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <smbsrv/alloc.h>
 #include <smbsrv/string.h>
 #include <smbsrv/smbinfo.h>
 #include <smbsrv/smb_token.h>
 #include <smbsrv/smb_xdr.h>
 
-#ifndef _KERNEL
-#include <assert.h>
-#define	ASSERT assert
-void (*smb_token_logfunc)(int, const char *, ...) = syslog;
-int smb_token_errlog = LOG_ERR;
-int smb_token_infolog = LOG_INFO;
-#else /* _KERNEL */
-void (*smb_token_logfunc)(int, const char *, ...) = cmn_err;
-int smb_token_errlog = CE_WARN;
-int smb_token_infolog = CE_NOTE;
-#endif /* _KERNEL */
-
-int smb_token_debug = 0;
-
-#ifdef _KERNEL
-extern char *inet_ntop(int, const void *, char *, int);
-#endif /* _KERNEL */
-
-/*
- * Returns -1 on error. Otherwise, returns 0.
- */
-int
-smb_token_tobuf(smb_dr_user_ctx_t *usr, char *buf, int len)
-{
-	char ipaddr_buf[INET_ADDRSTRLEN];
-
-	if (!usr) {
-		(void) strcpy(buf, "N/A");
-		return (-1);
-	}
-
-	(void) inet_ntop(AF_INET, (char *)&usr->du_ipaddr, ipaddr_buf,
-	    sizeof (ipaddr_buf));
-	(void) snprintf(buf, len, "%s\\%s %s (%s)",
-	    usr->du_domain ? usr->du_domain : "",
-	    usr->du_account ? usr->du_account : "",
-	    usr->du_workstation ? usr->du_workstation : "",
-	    ipaddr_buf);
-
-	return (0);
-}
-
-/*PRINTFLIKE3*/
-void
-smb_token_log(int level, smb_dr_user_ctx_t *usr, char *fmt, ...)
-{
-	va_list ap;
-	char *msg;
-	int len;
-	char tokenbuf[NTTOKEN_BASIC_INFO_MAXLEN];
-
-	msg = MEM_MALLOC("nttoken", 1024);
-	if (!msg) {
-		smb_token_logfunc(smb_token_errlog, "smb_token_log: "
-		    "resource shortage");
-		return;
-	}
-
-	if (usr)
-		(void) smb_token_tobuf(usr, tokenbuf, sizeof (tokenbuf));
-	else
-		(void) strcpy(tokenbuf, "UNKNOWN");
-
-	va_start(ap, fmt);
-	(void) snprintf(msg, 1024, "Token[%s]: ", tokenbuf);
-	len = strlen(msg);
-	(void) vsnprintf(msg + len, 1024 - len, fmt, ap);
-	va_end(ap);
-#ifdef _KERNEL
-	cmn_err(level, "%s", msg);
-#else
-	syslog(level, "%s", msg);
-#endif /* _KERNEL */
-
-	MEM_FREE("nttoken", msg);
-}
-
-#ifndef _KERNEL
-/*
- * smb_token_print
- *
- * Diagnostic routine to write the contents of a token to the log.
- */
-void
-smb_token_print(smb_token_t *token)
-{
-	smb_win_grps_t *w_grps;
-	smb_posix_grps_t *x_grps;
-	smb_sid_attrs_t *grp;
-	char sidstr[128];
-	int i;
-
-	if (token == NULL)
-		return;
-
-	smb_token_logfunc(smb_token_infolog, "Token for %s\\%s",
-	    (token->tkn_domain_name) ? token->tkn_domain_name : "-NULL-",
-	    (token->tkn_account_name) ? token->tkn_account_name : "-NULL-");
-
-	smb_token_logfunc(smb_token_infolog, "   User->Attr: %d",
-	    token->tkn_user->i_sidattr.attrs);
-	nt_sid_format2((nt_sid_t *)token->tkn_user->i_sidattr.sid, sidstr);
-	smb_token_logfunc(smb_token_infolog, "   User->Sid: %s (id=%u)",
-	    sidstr, token->tkn_user->i_id);
-
-	nt_sid_format2((nt_sid_t *)token->tkn_owner->i_sidattr.sid, sidstr);
-	smb_token_logfunc(smb_token_infolog, "   Ownr->Sid: %s (id=%u)",
-	    sidstr, token->tkn_owner->i_id);
-
-	nt_sid_format2((nt_sid_t *)token->tkn_primary_grp->i_sidattr.sid,
-	    sidstr);
-	smb_token_logfunc(smb_token_infolog, "   PGrp->Sid: %s (id=%u)",
-	    sidstr, token->tkn_primary_grp->i_id);
-
-	w_grps = token->tkn_win_grps;
-	if (w_grps) {
-		smb_token_logfunc(smb_token_infolog, "   Windows groups: %d",
-		    w_grps->wg_count);
-
-		for (i = 0; i < w_grps->wg_count; ++i) {
-			grp = &w_grps->wg_groups[i].i_sidattr;
-			smb_token_logfunc(smb_token_infolog,
-			    "    Grp[%d].Attr:%d", i, grp->attrs);
-			if (w_grps->wg_groups[i].i_sidattr.sid) {
-				nt_sid_format2((nt_sid_t *)grp->sid, sidstr);
-				smb_token_logfunc(smb_token_infolog,
-				    "    Grp[%d].Sid: %s (id=%u)", i, sidstr,
-				    w_grps->wg_groups[i].i_id);
-			}
-		}
-	}
-	else
-		smb_token_logfunc(smb_token_infolog, "   No Windows groups");
-
-	x_grps = token->tkn_posix_grps;
-	if (x_grps) {
-		smb_token_logfunc(smb_token_infolog, "   Solaris groups: %d",
-		    x_grps->pg_ngrps);
-		for (i = 0; i < x_grps->pg_ngrps; i++)
-			smb_token_logfunc(smb_token_infolog, "    %u",
-			    x_grps->pg_grps[i]);
-	}
-	else
-		smb_token_logfunc(smb_token_infolog, "   No Solaris groups");
-
-	if (token->tkn_privileges)
-		smb_privset_log(token->tkn_privileges);
-	else
-		smb_token_logfunc(smb_token_infolog, "   No privileges");
-}
-#endif /* _KERNEL */
-
 /*
  * smb_token_query_privilege
  *
@@ -253,24 +87,21 @@
 	XDR xdrs;
 
 	if (!obj) {
-		smb_token_logfunc(smb_token_errlog,
-		    "smb_token_mkselfrel: invalid parameter");
+		syslog(LOG_ERR, "smb_token_mkselfrel: invalid parameter");
 		return (NULL);
 	}
 
 	*len = xdr_sizeof(xdr_smb_token_t, obj);
 	buf = (uint8_t *)malloc(*len);
 	if (!buf) {
-		smb_token_logfunc(smb_token_errlog,
-		    "smb_token_mkselfrel: resource shortage");
+		syslog(LOG_ERR, "smb_token_mkselfrel: resource shortage");
 		return (NULL);
 	}
 
 	xdrmem_create(&xdrs, (const caddr_t)buf, *len, XDR_ENCODE);
 
 	if (!xdr_smb_token_t(&xdrs, obj)) {
-		smb_token_logfunc(smb_token_errlog,
-		    "smb_token_mkselfrel: XDR encode error");
+		syslog(LOG_ERR, "smb_token_mkselfrel: XDR encode error");
 		*len = 0;
 		free(buf);
 		buf = NULL;
@@ -294,16 +125,14 @@
 	xdrmem_create(&xdrs, (const caddr_t)buf, len, XDR_DECODE);
 	obj = (netr_client_t *)malloc(sizeof (netr_client_t));
 	if (!obj) {
-		smb_token_logfunc(smb_token_errlog, "netr_client_mkabsolute: "
-		    "resource shortage");
+		syslog(LOG_ERR, "netr_client_mkabsolute: resource shortage");
 		xdr_destroy(&xdrs);
 		return (NULL);
 	}
 
 	bzero(obj, sizeof (netr_client_t));
 	if (!xdr_netr_client_t(&xdrs, obj)) {
-		smb_token_logfunc(smb_token_errlog, "netr_client_mkabsolute: "
-		    "XDR decode error");
+		syslog(LOG_ERR, "netr_client_mkabsolute: XDR decode error");
 		free(obj);
 		obj = NULL;
 	}
@@ -334,8 +163,7 @@
 	obj = kmem_zalloc(sizeof (smb_token_t), KM_SLEEP);
 
 	if (!xdr_smb_token_t(&xdrs, obj)) {
-		smb_token_logfunc(smb_token_errlog, "smb_token_mkabsolute: XDR "
-		    "decode error");
+		cmn_err(CE_NOTE, "smb_token_mkabsolute: XDR decode error");
 		kmem_free(obj, sizeof (smb_token_t));
 		obj = NULL;
 	}
@@ -362,8 +190,7 @@
 	xdrmem_create(&xdrs, (const caddr_t)buf, *len, XDR_ENCODE);
 
 	if (!xdr_netr_client_t(&xdrs, obj)) {
-		smb_token_logfunc(smb_token_errlog, "netr_client_mkselfrel: "
-		    "XDR encode error");
+		cmn_err(CE_NOTE, "netr_client_mkselfrel: XDR encode error");
 		kmem_free(buf, *len);
 		*len = 0;
 		buf = NULL;
--- a/usr/src/common/smbsrv/smb_token_xdr.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/common/smbsrv/smb_token_xdr.c	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -34,12 +34,12 @@
 #endif /* !_KERNEL */
 #include <smbsrv/smb_vops.h>
 #include <smbsrv/wintypes.h>
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 #include <smbsrv/smb_xdr.h>
 #include <smbsrv/smb_token.h>
 
-bool_t
-xdr_ntsid_helper(xdrs, sid)
+static bool_t
+xdr_sid_helper(xdrs, sid)
 	XDR *xdrs;
 	char **sid;
 {
@@ -50,7 +50,7 @@
 	switch (xdrs->x_op) {
 	case XDR_DECODE:
 		/*
-		 * chicken-and-egg: Can't use nt_sid_length() since it takes
+		 * chicken-and-egg: Can't use smb_sid_len() since it takes
 		 * SID as its parameter while sid is yet to be decoded.
 		 */
 		pos = xdr_getpos(xdrs);
@@ -69,10 +69,10 @@
 		if (rc == FALSE)
 			return (FALSE);
 
-		len = sizeof (nt_sid_t) - sizeof (uint32_t) +
+		len = sizeof (smb_sid_t) - sizeof (uint32_t) +
 		    (cnt * sizeof (uint32_t));
 
-		if (!xdr_pointer(xdrs, sid, len, (xdrproc_t)xdr_nt_sid_t))
+		if (!xdr_pointer(xdrs, sid, len, (xdrproc_t)xdr_smb_sid_t))
 			return (FALSE);
 		break;
 
@@ -81,8 +81,8 @@
 		if (*sid == NULL)
 			return (FALSE);
 
-		len = nt_sid_length((nt_sid_t *)(uintptr_t)*sid);
-		if (!xdr_pointer(xdrs, sid, len, (xdrproc_t)xdr_nt_sid_t))
+		len = smb_sid_len((smb_sid_t *)(uintptr_t)*sid);
+		if (!xdr_pointer(xdrs, sid, len, (xdrproc_t)xdr_smb_sid_t))
 			return (FALSE);
 		break;
 	}
@@ -293,18 +293,18 @@
 }
 
 bool_t
-xdr_nt_sid_t(xdrs, objp)
+xdr_smb_sid_t(xdrs, objp)
 	XDR *xdrs;
-	nt_sid_t *objp;
+	smb_sid_t *objp;
 {
-	if (!xdr_uint8_t(xdrs, &objp->Revision))
+	if (!xdr_uint8_t(xdrs, &objp->sid_revision))
 		return (FALSE);
-	if (!xdr_uint8_t(xdrs, &objp->SubAuthCount))
+	if (!xdr_uint8_t(xdrs, &objp->sid_subauthcnt))
 		return (FALSE);
-	if (!xdr_vector(xdrs, (char *)objp->Authority, NT_SID_AUTH_MAX,
+	if (!xdr_vector(xdrs, (char *)objp->sid_authority, NT_SID_AUTH_MAX,
 	    sizeof (uint8_t), (xdrproc_t)xdr_uint8_t))
 		return (FALSE);
-	if (!xdr_vector(xdrs, (char *)objp->SubAuthority, objp->SubAuthCount,
+	if (!xdr_vector(xdrs, (char *)objp->sid_subauth, objp->sid_subauthcnt,
 	    sizeof (uint32_t), (xdrproc_t)xdr_uint32_t))
 		return (FALSE);
 	return (TRUE);
@@ -357,7 +357,7 @@
 {
 	if (!xdr_uint32_t(xdrs, &objp->attrs))
 		return (FALSE);
-	return (xdr_ntsid_helper(xdrs, (char **)&objp->sid));
+	return (xdr_sid_helper(xdrs, (char **)&objp->sid));
 }
 
 bool_t
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c	Mon Apr 14 10:40:32 2008 -0700
@@ -43,7 +43,6 @@
 #include <smbsrv/ndr.h>
 #include <smbsrv/mlrpc.h>
 #include <smbsrv/mlsvc_util.h>
-#include <smbsrv/ntsid.h>
 #include <smbsrv/smb_winpipe.h>
 
 /*
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c	Mon Apr 14 10:40:32 2008 -0700
@@ -36,7 +36,7 @@
 #include <smbsrv/libsmb.h>
 #include <smbsrv/ndr.h>
 #include <smbsrv/mlrpc.h>
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 
 
 /*
@@ -221,7 +221,7 @@
 {
 	static ndr_hdid_t uuid;
 	ndr_handle_t *hd;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 
 	if ((hd = malloc(sizeof (ndr_handle_t))) == NULL)
 		return (NULL);
@@ -232,9 +232,9 @@
 
 		uuid.data[0] = 0;
 		uuid.data[1] = 0;
-		uuid.data[2] = sid->SubAuthority[1];
-		uuid.data[3] = sid->SubAuthority[2];
-		uuid.data[4] = sid->SubAuthority[3];
+		uuid.data[2] = sid->sid_subauth[1];
+		uuid.data[3] = sid->sid_subauth[2];
+		uuid.data[4] = sid->sid_subauth[3];
 	}
 
 	++uuid.data[1];
--- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h	Mon Apr 14 10:40:32 2008 -0700
@@ -29,7 +29,7 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <sys/types.h>
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 #include <smbsrv/hash_table.h>
 #include <smbsrv/smb_token.h>
 #include <smbsrv/smb_privilege.h>
@@ -41,8 +41,8 @@
 #endif
 
 extern int mlsvc_init(void);
-extern uint32_t mlsvc_lookup_name(char *, nt_sid_t **, uint16_t *);
-extern uint32_t mlsvc_lookup_sid(nt_sid_t *, char **);
+extern uint32_t mlsvc_lookup_name(char *, smb_sid_t **, uint16_t *);
+extern uint32_t mlsvc_lookup_sid(smb_sid_t *, char **);
 extern DWORD mlsvc_netlogon(char *, char *);
 extern DWORD lsa_query_primary_domain_info(void);
 extern DWORD lsa_query_account_domain_info(void);
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c	Mon Apr 14 10:40:32 2008 -0700
@@ -42,7 +42,6 @@
 #include <smbsrv/lsalib.h>
 #include <smbsrv/ntstatus.h>
 #include <smbsrv/smbinfo.h>
-#include <smbsrv/ntsid.h>
 #include <smbsrv/smb_token.h>
 
 /*
@@ -57,14 +56,14 @@
 static uint32_t lsa_lookup_name_builtin(char *, smb_userinfo_t *);
 static uint32_t lsa_lookup_name_local(char *, char *, uint16_t,
     smb_userinfo_t *);
-static uint32_t lsa_lookup_name_lusr(char *, nt_sid_t **);
-static uint32_t lsa_lookup_name_lgrp(char *, nt_sid_t **);
+static uint32_t lsa_lookup_name_lusr(char *, smb_sid_t **);
+static uint32_t lsa_lookup_name_lgrp(char *, smb_sid_t **);
 static uint32_t lsa_lookup_name_domain(char *, char *, char *,
     smb_userinfo_t *);
 
-static uint32_t lsa_lookup_sid_builtin(nt_sid_t *, smb_userinfo_t *);
-static uint32_t lsa_lookup_sid_local(nt_sid_t *, smb_userinfo_t *);
-static uint32_t lsa_lookup_sid_domain(nt_sid_t *, smb_userinfo_t *);
+static uint32_t lsa_lookup_sid_builtin(smb_sid_t *, smb_userinfo_t *);
+static uint32_t lsa_lookup_sid_local(smb_sid_t *, smb_userinfo_t *);
+static uint32_t lsa_lookup_sid_domain(smb_sid_t *, smb_userinfo_t *);
 
 static int lsa_list_accounts(mlsvc_handle_t *);
 
@@ -135,15 +134,15 @@
 }
 
 uint32_t
-lsa_lookup_sid(nt_sid_t *sid, smb_userinfo_t *ainfo)
+lsa_lookup_sid(smb_sid_t *sid, smb_userinfo_t *ainfo)
 {
-	if (!nt_sid_is_valid(sid))
+	if (!smb_sid_isvalid(sid))
 		return (NT_STATUS_INVALID_SID);
 
-	if (nt_sid_is_local(sid))
+	if (smb_sid_islocal(sid))
 		return (lsa_lookup_sid_local(sid, ainfo));
 
-	if (nt_builtin_lookup_sid(sid, NULL))
+	if (smb_wka_lookup_sid(sid, NULL))
 		return (lsa_lookup_sid_builtin(sid, ainfo));
 
 	return (lsa_lookup_sid_domain(sid, ainfo));
@@ -255,18 +254,18 @@
 	char *domain;
 	int res;
 
-	user_info->user_sid = nt_builtin_lookup_name(account_name,
+	user_info->user_sid = smb_wka_lookup_name(account_name,
 	    &user_info->sid_name_use);
 
 	if (user_info->user_sid == NULL)
 		return (NT_STATUS_NONE_MAPPED);
 
-	user_info->domain_sid = nt_sid_dup(user_info->user_sid);
-	res = nt_sid_split(user_info->domain_sid, &user_info->rid);
+	user_info->domain_sid = smb_sid_dup(user_info->user_sid);
+	res = smb_sid_split(user_info->domain_sid, &user_info->rid);
 	if (res < 0)
 		return (NT_STATUS_INTERNAL_ERROR);
 
-	domain = nt_builtin_lookup_domain(account_name);
+	domain = smb_wka_lookup_domain(account_name);
 	if (domain) {
 		user_info->domain_name = strdup(domain);
 		return (NT_STATUS_SUCCESS);
@@ -293,7 +292,7 @@
     smb_userinfo_t *ainfo)
 {
 	char hostname[MAXHOSTNAMELEN];
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	uint32_t status;
 
 	switch (sid_type) {
@@ -331,11 +330,11 @@
 
 	ainfo->sid_name_use = sid_type;
 	ainfo->user_sid = sid;
-	ainfo->domain_sid = nt_sid_dup(sid);
+	ainfo->domain_sid = smb_sid_dup(sid);
 	if (ainfo->domain_sid == NULL)
 		return (NT_STATUS_NO_MEMORY);
 
-	(void) nt_sid_split(ainfo->domain_sid, &ainfo->rid);
+	(void) smb_sid_split(ainfo->domain_sid, &ainfo->rid);
 	if ((domain == NULL) || (*domain == '\0')) {
 		(void) smb_getnetbiosname(hostname, sizeof (hostname));
 		ainfo->domain_name = strdup(hostname);
@@ -394,7 +393,7 @@
 lsa_test_lookup(char *name)
 {
 	smb_userinfo_t *user_info;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	DWORD status;
 	smb_ntdomain_t *di;
 
@@ -408,7 +407,7 @@
 		    user_info);
 
 		if (status == 0) {
-			sid = nt_sid_splice(user_info->domain_sid,
+			sid = smb_sid_splice(user_info->domain_sid,
 			    user_info->rid);
 
 			(void) lsa_lookup_sid_domain(sid, user_info);
@@ -545,7 +544,7 @@
 		for (i = 0; i < accounts.entries_read; ++i) {
 			sid = accounts.info[i].sid;
 
-			name = nt_builtin_lookup_sid((nt_sid_t *)sid,
+			name = smb_wka_lookup_sid((smb_sid_t *)sid,
 			    &sid_name_use);
 
 			if (name == 0) {
@@ -559,8 +558,6 @@
 				}
 			}
 
-			nt_sid_logf((nt_sid_t *)sid);
-
 			if (lsar_open_account(domain_handle, sid,
 			    &account_handle) == 0) {
 				(void) lsar_enum_privs_account(&account_handle,
@@ -591,7 +588,7 @@
  * a domain SID if local users are mapped to domain users.
  */
 static uint32_t
-lsa_lookup_name_lusr(char *name, nt_sid_t **sid)
+lsa_lookup_name_lusr(char *name, smb_sid_t **sid)
 {
 	struct passwd *pw;
 
@@ -615,7 +612,7 @@
  * a domain SID if local groups are mapped to domain groups.
  */
 static uint32_t
-lsa_lookup_name_lgrp(char *name, nt_sid_t **sid)
+lsa_lookup_name_lgrp(char *name, smb_sid_t **sid)
 {
 	struct group *gr;
 
@@ -633,7 +630,7 @@
 {
 	int lookup_mode;
 
-	if (nt_builtin_lookup((char *)name))
+	if (smb_wka_lookup((char *)name))
 		return (MLSVC_LOOKUP_BUILTIN);
 
 	if (smb_config_get_secmode() == SMB_SECMODE_WORKGRP)
@@ -651,7 +648,7 @@
 }
 
 static uint32_t
-lsa_lookup_sid_local(nt_sid_t *sid, smb_userinfo_t *ainfo)
+lsa_lookup_sid_local(smb_sid_t *sid, smb_userinfo_t *ainfo)
 {
 	char hostname[MAXHOSTNAMELEN];
 	struct passwd *pw;
@@ -687,8 +684,8 @@
 	if (ainfo->name == NULL)
 		return (NT_STATUS_NO_MEMORY);
 
-	ainfo->domain_sid = nt_sid_dup(sid);
-	if (nt_sid_split(ainfo->domain_sid, &ainfo->rid) < 0)
+	ainfo->domain_sid = smb_sid_dup(sid);
+	if (smb_sid_split(ainfo->domain_sid, &ainfo->rid) < 0)
 		return (NT_STATUS_INTERNAL_ERROR);
 	*hostname = '\0';
 	(void) smb_getnetbiosname(hostname, MAXHOSTNAMELEN);
@@ -699,25 +696,25 @@
 }
 
 static uint32_t
-lsa_lookup_sid_builtin(nt_sid_t *sid, smb_userinfo_t *ainfo)
+lsa_lookup_sid_builtin(smb_sid_t *sid, smb_userinfo_t *ainfo)
 {
 	char *name;
 	WORD sid_name_use;
 
-	if ((name = nt_builtin_lookup_sid(sid, &sid_name_use)) == NULL)
+	if ((name = smb_wka_lookup_sid(sid, &sid_name_use)) == NULL)
 		return (NT_STATUS_NONE_MAPPED);
 
 	ainfo->sid_name_use = sid_name_use;
 	ainfo->name = strdup(name);
-	ainfo->domain_sid = nt_sid_dup(sid);
+	ainfo->domain_sid = smb_sid_dup(sid);
 
 	if (ainfo->name == NULL || ainfo->domain_sid == NULL)
 		return (NT_STATUS_NO_MEMORY);
 
 	if (sid_name_use != SidTypeDomain)
-		(void) nt_sid_split(ainfo->domain_sid, &ainfo->rid);
+		(void) smb_sid_split(ainfo->domain_sid, &ainfo->rid);
 
-	if ((name = nt_builtin_lookup_domain(ainfo->name)) != NULL)
+	if ((name = smb_wka_lookup_domain(ainfo->name)) != NULL)
 		ainfo->domain_name = strdup(name);
 	else
 		ainfo->domain_name = strdup("UNKNOWN");
@@ -729,7 +726,7 @@
 }
 
 static uint32_t
-lsa_lookup_sid_domain(nt_sid_t *sid, smb_userinfo_t *ainfo)
+lsa_lookup_sid_domain(smb_sid_t *sid, smb_userinfo_t *ainfo)
 {
 	mlsvc_handle_t domain_handle;
 	char *user = smbrdr_ipc_get_user();
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c	Mon Apr 14 10:40:32 2008 -0700
@@ -137,7 +137,7 @@
 			nt_domain_flush(NT_DOMAIN_PRIMARY);
 			nt_new_dp = nt_domain_new(NT_DOMAIN_PRIMARY,
 			    (char *)pd_info->name.str,
-			    (nt_sid_t *)pd_info->sid);
+			    (smb_sid_t *)pd_info->sid);
 			(void) nt_domain_add(nt_new_dp);
 			status = NT_STATUS_SUCCESS;
 			break;
@@ -148,7 +148,7 @@
 			nt_domain_flush(NT_DOMAIN_ACCOUNT);
 			nt_new_dp = nt_domain_new(NT_DOMAIN_ACCOUNT,
 			    (char *)ad_info->name.str,
-			    (nt_sid_t *)ad_info->sid);
+			    (smb_sid_t *)ad_info->sid);
 			(void) nt_domain_add(nt_new_dp);
 			status = NT_STATUS_SUCCESS;
 			break;
@@ -259,12 +259,12 @@
 		} else {
 			domain_entry =
 			    &arg.domain_table->entries[index];
-			user_info->domain_sid = nt_sid_dup(
-			    (nt_sid_t *)domain_entry->domain_sid);
+			user_info->domain_sid = smb_sid_dup(
+			    (smb_sid_t *)domain_entry->domain_sid);
 			user_info->domain_name = MEM_STRDUP("mlrpc",
 			    (const char *)
 			    domain_entry->domain_name.str);
-			user_info->user_sid = nt_sid_splice(
+			user_info->user_sid = smb_sid_splice(
 			    user_info->domain_sid, user_info->rid);
 		}
 		status = NT_STATUS_SUCCESS;
@@ -342,8 +342,8 @@
 			domain_entry =
 			    &arg.domain_table->entries[index];
 
-			user_info->domain_sid = nt_sid_dup(
-			    (nt_sid_t *)domain_entry->domain_sid);
+			user_info->domain_sid = smb_sid_dup(
+			    (smb_sid_t *)domain_entry->domain_sid);
 
 			user_info->domain_name = MEM_STRDUP("mlrpc",
 			    (const char *)
@@ -412,16 +412,14 @@
 			n_entries = arg.enum_buf->entries_read;
 			nbytes = n_entries * sizeof (struct mslsa_AccountInfo);
 
-			info = (struct mslsa_AccountInfo *)MEM_MALLOC("mlrpc",
-			    nbytes);
-			if (info == NULL) {
+			if ((info = malloc(nbytes)) == NULL) {
 				mlsvc_rpc_free(context, &heap);
 				return (-1);
 			}
 
 			for (i = 0; i < n_entries; ++i)
-				info[i].sid = (struct mslsa_sid *)nt_sid_dup(
-				    (nt_sid_t *)arg.enum_buf->info[i].sid);
+				info[i].sid = (struct mslsa_sid *)smb_sid_dup(
+				    (smb_sid_t *)arg.enum_buf->info[i].sid);
 
 			accounts->entries_read = n_entries;
 			accounts->info = info;
@@ -492,7 +490,7 @@
 			nt_new_dp = nt_domain_new(
 			    NT_DOMAIN_TRUSTED,
 			    (char *)arg.enum_buf->info[i].name.str,
-			    (nt_sid_t *)arg.enum_buf->info[i].sid);
+			    (smb_sid_t *)arg.enum_buf->info[i].sid);
 
 			(void) nt_domain_add(nt_new_dp);
 		}
@@ -756,8 +754,8 @@
 		} else {
 			domain_entry = &arg.domain_table->entries[index];
 
-			user_info->domain_sid = nt_sid_dup(
-			    (nt_sid_t *)domain_entry->domain_sid);
+			user_info->domain_sid = smb_sid_dup(
+			    (smb_sid_t *)domain_entry->domain_sid);
 
 			user_info->domain_name = MEM_STRDUP("mlrpc",
 			    (char const *)domain_entry->domain_name.str);
@@ -848,12 +846,12 @@
 		} else {
 			domain_entry = &arg.domain_table->entries[index];
 
-			user_info->domain_sid = nt_sid_dup(
-			    (nt_sid_t *)domain_entry->domain_sid);
+			user_info->domain_sid = smb_sid_dup(
+			    (smb_sid_t *)domain_entry->domain_sid);
 
 			user_info->domain_name = MEM_STRDUP("mlrpc",
 			    (char const *)domain_entry->domain_name.str);
-			user_info->user_sid = nt_sid_splice(
+			user_info->user_sid = smb_sid_splice(
 			    user_info->domain_sid, user_info->rid);
 		}
 		status = NT_STATUS_SUCCESS;
--- a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers	Mon Apr 14 10:40:32 2008 -0700
@@ -56,6 +56,7 @@
 	mlsvc_netlogon;
 	smb_logon;
 	smb_token_destroy;
+	smb_token_log;
 	smb_build_lmshare_info;
 	smb_get_smb_share_group;
 	smb_autohome_add;
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c	Mon Apr 14 10:40:32 2008 -0700
@@ -647,7 +647,7 @@
     struct mlrpc_xaction *mxa)
 {
 	char domain_name[MLSVC_DOMAIN_NAME_MAX];
-	nt_sid_t *sid = NULL;
+	smb_sid_t *sid = NULL;
 	int security_mode;
 	int rc;
 
@@ -655,7 +655,7 @@
 
 	if (security_mode != SMB_SECMODE_DOMAIN) {
 		rc = smb_gethostname(domain_name, MLSVC_DOMAIN_NAME_MAX, 1);
-		sid = nt_sid_dup(nt_domain_local_sid());
+		sid = smb_sid_dup(nt_domain_local_sid());
 	} else {
 		rc = smb_getdomainname(domain_name, MLSVC_DOMAIN_NAME_MAX);
 		sid = smb_getdomainsid();
@@ -688,7 +688,7 @@
     struct mlrpc_xaction *mxa)
 {
 	char domain_name[MLSVC_DOMAIN_NAME_MAX];
-	nt_sid_t *domain_sid;
+	smb_sid_t *domain_sid;
 	int rc;
 
 	if (smb_gethostname(domain_name, MLSVC_DOMAIN_NAME_MAX, 1) != 0)
@@ -808,7 +808,7 @@
 	struct mslsa_name_entry *names;
 	struct mslsa_name_entry *name;
 	smb_userinfo_t *user_info;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	DWORD n_entry;
 	int result;
 	int i;
@@ -835,7 +835,7 @@
 	name = names;
 	for (i = 0; i < n_entry; ++i, name++) {
 		bzero(&names[i], sizeof (struct mslsa_name_entry));
-		sid = (nt_sid_t *)param->lup_sid_table.entries[i].psid;
+		sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
 
 		result = lsa_lookup_sid(sid, user_info);
 		if (result != NT_STATUS_SUCCESS)
@@ -914,7 +914,7 @@
 		return (-1);
 
 	for (i = 0; i < n_entry; ++i) {
-		if (nt_sid_is_equal((nt_sid_t *)dentry[i].domain_sid,
+		if (smb_sid_cmp((smb_sid_t *)dentry[i].domain_sid,
 		    user_info->domain_sid)) {
 			*domain_idx = i;
 			return (0);
@@ -954,7 +954,7 @@
 	struct mslsa_domain_table *domain_table;
 	struct mslsa_domain_entry *domain_entry;
 	smb_userinfo_t *user_info;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	DWORD n_entry;
 	int result;
 	int i;
@@ -981,7 +981,7 @@
 	name = names;
 	for (i = 0; i < n_entry; ++i, name++) {
 		bzero(name, sizeof (struct lsar_name_entry2));
-		sid = (nt_sid_t *)param->lup_sid_table.entries[i].psid;
+		sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
 
 		result = lsa_lookup_sid(sid, user_info);
 		if (result != NT_STATUS_SUCCESS)
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c	Mon Apr 14 10:40:32 2008 -0700
@@ -37,11 +37,11 @@
 
 #include <smbsrv/libsmb.h>
 #include <smbsrv/libmlrpc.h>
+#include <smbsrv/libmlsvc.h>
+
 #include <smbsrv/ntstatus.h>
-#include <smbsrv/ntsid.h>
 #include <smbsrv/smbinfo.h>
 #include <smbsrv/nmpipes.h>
-#include <smbsrv/libmlsvc.h>
 #include <smbsrv/mlsvc_util.h>
 #include <smbsrv/ndl/samrpc.ndl>
 #include <smbsrv/samlib.h>
@@ -232,7 +232,7 @@
 	struct samr_LookupDomain *param = arg;
 	char resource_domain[SMB_PI_MAX_DOMAIN];
 	char *domain_name;
-	nt_sid_t *sid = NULL;
+	smb_sid_t *sid = NULL;
 
 	if ((domain_name = (char *)param->domain_name.str) == NULL) {
 		bzero(param, sizeof (struct samr_LookupDomain));
@@ -242,7 +242,7 @@
 
 	(void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);
 	if (mlsvc_is_local_domain(domain_name) == 1) {
-		sid = nt_sid_dup(nt_domain_local_sid());
+		sid = smb_sid_dup(nt_domain_local_sid());
 	} else if (strcasecmp(resource_domain, domain_name) == 0) {
 		/*
 		 * We should not be asked to provide
@@ -250,7 +250,7 @@
 		 */
 		sid = NULL;
 	} else {
-		sid = nt_builtin_lookup_name(domain_name, 0);
+		sid = smb_wka_lookup_name(domain_name, 0);
 	}
 
 	if (sid) {
@@ -368,7 +368,7 @@
 		return (MLRPC_DRC_OK);
 	}
 
-	if ((domain = nt_domain_lookup_sid((nt_sid_t *)param->sid)) == NULL) {
+	if ((domain = nt_domain_lookup_sid((smb_sid_t *)param->sid)) == NULL) {
 		bzero(&param->domain_handle, sizeof (samr_handle_t));
 		param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
 		return (MLRPC_DRC_OK);
@@ -524,10 +524,10 @@
 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
 	ndr_handle_t *hd;
 	samr_keydata_t *data;
-	well_known_account_t *wka;
+	smb_wka_t *wka;
 	smb_group_t grp;
 	smb_passwd_t smbpw;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	uint32_t status = NT_STATUS_SUCCESS;
 	int rc;
 
@@ -558,12 +558,13 @@
 
 	switch (data->kd_type) {
 	case NT_DOMAIN_BUILTIN:
-		wka = nt_builtin_lookup((char *)param->name.str);
+		wka = smb_wka_lookup((char *)param->name.str);
 		if (wka != NULL) {
 			param->rids.n_entry = 1;
-			(void) nt_sid_get_rid(wka->binsid, &param->rids.rid[0]);
+			(void) smb_sid_getrid(wka->wka_binsid,
+			    &param->rids.rid[0]);
 			param->rid_types.n_entry = 1;
-			param->rid_types.rid_type[0] = wka->sid_name_use;
+			param->rid_types.rid_type[0] = wka->wka_type;
 			param->status = NT_STATUS_SUCCESS;
 			return (MLRPC_DRC_OK);
 		}
@@ -586,7 +587,7 @@
 			if (smb_idmap_getsid(smbpw.pw_uid, SMB_IDMAP_USER,
 			    &sid) == IDMAP_SUCCESS) {
 				param->rids.n_entry = 1;
-				(void) nt_sid_get_rid(sid, &param->rids.rid[0]);
+				(void) smb_sid_getrid(sid, &param->rids.rid[0]);
 				param->rid_types.n_entry = 1;
 				param->rid_types.rid_type[0] = SidTypeUser;
 				param->status = NT_STATUS_SUCCESS;
@@ -703,9 +704,9 @@
 	ndr_hdid_t *id = (ndr_hdid_t *)&param->user_handle;
 	ndr_handle_t *hd;
 	samr_keydata_t *data;
-	well_known_account_t *wka;
-	nt_sid_t *user_sid = NULL;
-	nt_sid_t *dom_sid;
+	smb_wka_t *wka;
+	smb_sid_t *user_sid = NULL;
+	smb_sid_t *dom_sid;
 	smb_group_t grp;
 	smb_giter_t gi;
 	uint32_t status;
@@ -720,12 +721,12 @@
 	data = (samr_keydata_t *)hd->nh_data;
 	switch (data->kd_type) {
 	case NT_DOMAIN_BUILTIN:
-		wka = nt_builtin_lookup("builtin");
+		wka = smb_wka_lookup("builtin");
 		if (wka == NULL) {
 			status = NT_STATUS_INTERNAL_ERROR;
 			goto query_error;
 		}
-		dom_sid = wka->binsid;
+		dom_sid = wka->wka_binsid;
 		break;
 	case NT_DOMAIN_LOCAL:
 		dom_sid = nt_domain_local_sid();
@@ -735,7 +736,7 @@
 		goto query_error;
 	}
 
-	user_sid = nt_sid_splice(dom_sid, data->kd_rid);
+	user_sid = smb_sid_splice(dom_sid, data->kd_rid);
 	if (user_sid == NULL) {
 		status = NT_STATUS_NO_MEMORY;
 		goto query_error;
@@ -1169,7 +1170,7 @@
 		goto create_alias_err;
 	}
 
-	(void) nt_sid_get_rid(grp->sid, &param->rid);
+	(void) smb_sid_getrid(grp->sid, &param->rid);
 	nt_group_putinfo(grp);
 	handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_ALIAS_KEY,
 	    param->rid);
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c	Mon Apr 14 10:40:32 2008 -0700
@@ -45,7 +45,6 @@
 #include <smbsrv/libmlsvc.h>
 
 #include <smbsrv/smbinfo.h>
-#include <smbsrv/ntsid.h>
 #include <smbsrv/lsalib.h>
 #include <smbsrv/samlib.h>
 #include <smbsrv/mlsvc_util.h>
@@ -102,7 +101,7 @@
  * call free when it is no longer required.
  */
 uint32_t
-mlsvc_lookup_name(char *account, nt_sid_t **sid, uint16_t *sid_type)
+mlsvc_lookup_name(char *account, smb_sid_t **sid, uint16_t *sid_type)
 {
 	smb_userinfo_t *ainfo;
 	uint32_t status;
@@ -130,7 +129,7 @@
  * successful return.
  */
 uint32_t
-mlsvc_lookup_sid(nt_sid_t *sid, char **name)
+mlsvc_lookup_sid(smb_sid_t *sid, char **name)
 {
 	smb_userinfo_t *ainfo;
 	uint32_t status;
@@ -238,7 +237,7 @@
 	if ((domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY)) == NULL)
 		return;
 
-	if (!nt_sid_is_equal((nt_sid_t *)user_info->domain_sid, domain->sid))
+	if (!smb_sid_cmp((smb_sid_t *)user_info->domain_sid, domain->sid))
 		return;
 
 	if (user_info->rid == DOMAIN_USER_RID_ADMIN)
@@ -289,18 +288,18 @@
  * Expand the heap and copy the sid into the new area.
  * Returns a pointer to the copy of the sid on the heap.
  */
-nt_sid_t *
-mlsvc_sid_save(nt_sid_t *sid, struct mlrpc_xaction *mxa)
+smb_sid_t *
+mlsvc_sid_save(smb_sid_t *sid, struct mlrpc_xaction *mxa)
 {
-	nt_sid_t *heap_sid;
+	smb_sid_t *heap_sid;
 	unsigned size;
 
 	if (sid == NULL)
 		return (NULL);
 
-	size = nt_sid_length(sid);
+	size = smb_sid_len(sid);
 
-	if ((heap_sid = (nt_sid_t *)MLRPC_HEAP_MALLOC(mxa, size)) == NULL)
+	if ((heap_sid = (smb_sid_t *)MLRPC_HEAP_MALLOC(mxa, size)) == NULL)
 		return (0);
 
 	bcopy(sid, heap_sid, size);
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c	Mon Apr 14 10:40:32 2008 -0700
@@ -41,6 +41,7 @@
 
 #include <smbsrv/libsmb.h>
 #include <smbsrv/libsmbrdr.h>
+#include <smbsrv/libsmbns.h>
 #include <smbsrv/mlsvc_util.h>
 #include <smbsrv/ndl/netlogon.ndl>
 #include <smbsrv/ntstatus.h>
@@ -108,6 +109,19 @@
 		}
 	}
 
+	/*
+	 * The NETLOGON credential chain establishment has unset
+	 * both ServerPrincipalName and dNSHostName attributes of the
+	 * workstation trust account. Those attributes will be updated
+	 * here to avoid any Kerberos authentication errors from happening.
+	 *
+	 * Later, when NT4 domain controller is supported, we need to
+	 * find a way to disable the following code.
+	 */
+	if (ads_update_attrs() == -1)
+		syslog(LOG_DEBUG, "netlogon_auth: ServerPrincipalName"
+		    " and dNSHostName attributes might have been unset.");
+
 	return ((rc) ? NT_STATUS_UNSUCCESSFUL : NT_STATUS_SUCCESS);
 }
 
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c	Mon Apr 14 10:40:32 2008 -0700
@@ -150,17 +150,17 @@
 	user_info->sid_name_use = SidTypeUser;
 	user_info->rid = info3->UserId;
 	user_info->primary_group_rid = info3->PrimaryGroupId;
-	user_info->domain_sid = nt_sid_dup((nt_sid_t *)info3->LogonDomainId);
+	user_info->domain_sid = smb_sid_dup((smb_sid_t *)info3->LogonDomainId);
 
 	if (user_info->domain_sid == NULL)
 		return (NT_STATUS_NO_MEMORY);
 
-	user_info->user_sid = nt_sid_splice(user_info->domain_sid,
+	user_info->user_sid = smb_sid_splice(user_info->domain_sid,
 	    user_info->rid);
 	if (user_info->user_sid == NULL)
 		return (NT_STATUS_NO_MEMORY);
 
-	user_info->pgrp_sid = nt_sid_splice(user_info->domain_sid,
+	user_info->pgrp_sid = smb_sid_splice(user_info->domain_sid,
 	    user_info->primary_group_rid);
 	if (user_info->pgrp_sid == NULL)
 		return (NT_STATUS_NO_MEMORY);
@@ -197,8 +197,8 @@
 				other_grps[i].attrs =
 				    info3->ExtraSids[i].attributes;
 
-				other_grps[i].sid = nt_sid_dup(
-				    (nt_sid_t *)info3->ExtraSids[i].sid);
+				other_grps[i].sid = smb_sid_dup(
+				    (smb_sid_t *)info3->ExtraSids[i].sid);
 
 				if (other_grps[i].sid == NULL)
 					break;
--- a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c	Mon Apr 14 10:40:32 2008 -0700
@@ -37,9 +37,9 @@
 #include <smbsrv/libsmb.h>
 #include <smbsrv/libsmbrdr.h>
 #include <smbsrv/libmlsvc.h>
+
 #include <smbsrv/ntstatus.h>
 #include <smbsrv/ntaccess.h>
-#include <smbsrv/ntsid.h>
 #include <smbsrv/lsalib.h>
 #include <smbsrv/samlib.h>
 
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c	Mon Apr 14 10:40:32 2008 -0700
@@ -37,8 +37,9 @@
 #include <unistd.h>
 
 #include <smbsrv/libsmb.h>
+
 #include <smbsrv/ntstatus.h>
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 #include <smbsrv/samlib.h>
 #include <smbsrv/mlrpc.h>
 #include <smbsrv/mlsvc.h>
@@ -94,7 +95,7 @@
 	rc = mlsvc_rpc_call(context, opnum, &arg, &heap);
 	if (rc == 0) {
 		user_info->sid_name_use = SidTypeDomain;
-		user_info->domain_sid = nt_sid_dup((nt_sid_t *)arg.sid);
+		user_info->domain_sid = smb_sid_dup((smb_sid_t *)arg.sid);
 		user_info->domain_name = MEM_STRDUP("mlrpc", domain_name);
 	}
 
--- a/usr/src/lib/smbsrv/libmlsvc/common/secdb.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libmlsvc/common/secdb.c	Mon Apr 14 10:40:32 2008 -0700
@@ -41,7 +41,6 @@
 #include <smbsrv/smbinfo.h>
 #include <smbsrv/smb_token.h>
 #include <smbsrv/lsalib.h>
-#include <smbsrv/alloc.h>
 
 extern uint32_t netlogon_logon(netr_client_t *clnt, smb_userinfo_t *uinfo);
 static uint32_t smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo);
@@ -50,7 +49,7 @@
 
 static uint32_t smb_setup_luinfo(smb_userinfo_t *, netr_client_t *, uid_t);
 
-static int smb_token_is_member(smb_token_t *token, nt_sid_t *sid);
+static int smb_token_is_member(smb_token_t *token, smb_sid_t *sid);
 static int smb_token_is_valid(smb_token_t *token);
 static smb_win_grps_t *smb_token_create_wingrps(smb_userinfo_t *user_info);
 
@@ -288,7 +287,7 @@
 }
 
 static smb_id_t *
-smb_token_create_id(nt_sid_t *sid)
+smb_token_create_id(smb_sid_t *sid)
 {
 	smb_id_t *id;
 
@@ -298,7 +297,7 @@
 
 	id->i_id = (uid_t)-1;
 	id->i_sidattr.attrs = 7;
-	id->i_sidattr.sid = nt_sid_dup(sid);
+	id->i_sidattr.sid = smb_sid_dup(sid);
 
 	if (id->i_sidattr.sid == NULL) {
 		free(id);
@@ -321,13 +320,13 @@
 
 #ifdef PBSHORTCUT
 	if (user_info->flags & SMB_UINFO_FLAG_ADMIN) {
-		well_known_account_t *wka;
+		smb_wka_t *wka;
 		/*
 		 * Need Winchester update on Group ID as file owner issue.
 		 * For now, the file owner will always be set with user SID.
 		 */
-		wka = nt_builtin_lookup("Administratrors");
-		owner = smb_token_create_id(wka->binsid);
+		wka = smb_wka_lookup("Administratrors");
+		owner = smb_token_create_id(wka->wka_binsid);
 	} else
 #endif
 	owner = smb_token_create_id(user_info->user_sid);
@@ -378,7 +377,7 @@
 static void
 smb_token_set_flags(smb_token_t *token, smb_userinfo_t *user_info)
 {
-	well_known_account_t *wka;
+	smb_wka_t *wka;
 
 	if (user_info->flags & SMB_UINFO_FLAG_ANON) {
 		token->tkn_flags |= SMB_ATF_ANON;
@@ -390,16 +389,16 @@
 		return;
 	}
 
-	wka = nt_builtin_lookup("Administrators");
-	if (wka->binsid && smb_token_is_member(token, wka->binsid))
+	wka = smb_wka_lookup("Administrators");
+	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
 		token->tkn_flags |= SMB_ATF_ADMIN;
 
-	wka = nt_builtin_lookup("Power Users");
-	if (wka->binsid && smb_token_is_member(token, wka->binsid))
+	wka = smb_wka_lookup("Power Users");
+	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
 		token->tkn_flags |= SMB_ATF_POWERUSER;
 
-	wka = nt_builtin_lookup("Backup Operators");
-	if (wka->binsid && smb_token_is_member(token, wka->binsid))
+	wka = smb_wka_lookup("Backup Operators");
+	if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid))
 		token->tkn_flags |= SMB_ATF_BACKUPOP;
 
 }
@@ -525,7 +524,7 @@
 	smb_sid_attrs_t *dlg_grps;
 	smb_rid_attrs_t *g_grps;
 	smb_sid_attrs_t *grp;
-	nt_sid_t *builtin_sid;
+	smb_sid_t *builtin_sid;
 	smb_giter_t gi;
 	smb_group_t lgrp;
 	uint32_t n_gg, n_lg, n_dlg, n_wg;
@@ -561,7 +560,7 @@
 	g_grps = user_info->groups;
 	for (i = 0; i < n_gg; i++) {
 		grp = &tkn_grps->wg_groups[i].i_sidattr;
-		grp->sid = nt_sid_splice(user_info->domain_sid, g_grps[i].rid);
+		grp->sid = smb_sid_splice(user_info->domain_sid, g_grps[i].rid);
 		if (grp->sid == NULL)
 			break;
 		grp->attrs = g_grps[i].attributes;
@@ -573,7 +572,7 @@
 		 * primary group.
 		 */
 		grp = &tkn_grps->wg_groups[i].i_sidattr;
-		grp->sid = nt_sid_dup(user_info->pgrp_sid);
+		grp->sid = smb_sid_dup(user_info->pgrp_sid);
 		if (grp->sid != NULL) {
 			grp->attrs = 0x7;
 			i++;
@@ -584,7 +583,7 @@
 	dlg_grps = user_info->other_grps;
 	for (j = 0; j < n_dlg; j++, i++) {
 		grp = &tkn_grps->wg_groups[i].i_sidattr;
-		grp->sid = nt_sid_dup(dlg_grps[j].sid);
+		grp->sid = smb_sid_dup(dlg_grps[j].sid);
 		if (grp->sid == NULL)
 			break;
 		grp->attrs = dlg_grps[j].attrs;
@@ -597,7 +596,7 @@
 			if ((j < n_lg) &&
 			    smb_lgrp_is_member(&lgrp, user_info->user_sid)) {
 				grp = &tkn_grps->wg_groups[i].i_sidattr;
-				grp->sid = nt_sid_dup(lgrp.sg_id.gs_sid);
+				grp->sid = smb_sid_dup(lgrp.sg_id.gs_sid);
 				if (grp->sid == NULL) {
 					smb_lgrp_free(&lgrp);
 					break;
@@ -613,7 +612,7 @@
 
 	/* Add well known groups */
 	for (j = 0; j < n_wg; j++, i++) {
-		builtin_sid = nt_builtin_lookup_name(wk_grps[j], NULL);
+		builtin_sid = smb_wka_lookup_name(wk_grps[j], NULL);
 		if (builtin_sid == NULL)
 			break;
 		tkn_grps->wg_groups[i].i_sidattr.sid = builtin_sid;
@@ -788,7 +787,7 @@
 	char pwbuf[1024];
 
 	lui->sid_name_use = SidTypeUser;
-	lui->domain_sid = nt_sid_dup(nt_domain_local_sid());
+	lui->domain_sid = smb_sid_dup(nt_domain_local_sid());
 	lui->name = strdup(clnt->username);
 	lui->domain_name = strdup(clnt->domain);
 	lui->n_groups = 0;
@@ -802,8 +801,8 @@
 		return (NT_STATUS_INVALID_PARAMETER);
 
 	if (clnt->flags & NETR_CFLG_ANON) {
-		lui->user_sid = nt_builtin_lookup_name("Anonymous", NULL);
-		lui->pgrp_sid = nt_builtin_lookup_name("Anonymous", NULL);
+		lui->user_sid = smb_wka_lookup_name("Anonymous", NULL);
+		lui->pgrp_sid = smb_wka_lookup_name("Anonymous", NULL);
 		lui->flags = SMB_UINFO_FLAG_ANON;
 
 		if (lui->user_sid == NULL || lui->pgrp_sid == NULL)
@@ -846,10 +845,10 @@
 	}
 
 	lui->rid = umap->sim_rid;
-	lui->user_sid = nt_sid_dup(umap->sim_sid);
+	lui->user_sid = smb_sid_dup(umap->sim_sid);
 
 	lui->primary_group_rid = gmap->sim_rid;
-	lui->pgrp_sid = nt_sid_dup(gmap->sim_sid);
+	lui->pgrp_sid = smb_sid_dup(gmap->sim_sid);
 
 	smb_idmap_batch_destroy(&sib);
 
@@ -895,7 +894,7 @@
  * Return a pointer to the user SID in the specified token. A null
  * pointer indicates an error.
  */
-static nt_sid_t *
+static smb_sid_t *
 smb_token_user_sid(smb_token_t *token)
 {
 	if (token && token->tkn_user)
@@ -918,7 +917,7 @@
  * On success a pointer to the appropriate group SID will be returned.
  * Otherwise a null pointer will be returned.
  */
-static nt_sid_t *
+static smb_sid_t *
 smb_token_group_sid(smb_token_t *token, int *iterator)
 {
 	smb_win_grps_t *groups;
@@ -950,14 +949,14 @@
  * Returns 1 if the SID is a member of the token. Otherwise returns 0.
  */
 static int
-smb_token_is_member(smb_token_t *token, nt_sid_t *sid)
+smb_token_is_member(smb_token_t *token, smb_sid_t *sid)
 {
-	nt_sid_t *tsid;
+	smb_sid_t *tsid;
 	int iterator = 0;
 
 	tsid = smb_token_user_sid(token);
 	while (tsid) {
-		if (nt_sid_is_equal(tsid, sid))
+		if (smb_sid_cmp(tsid, sid))
 			return (1);
 
 		tsid = smb_token_group_sid(token, &iterator);
@@ -965,3 +964,76 @@
 
 	return (0);
 }
+
+/*
+ * smb_token_log
+ *
+ * Diagnostic routine to write the contents of a token to the log.
+ */
+void
+smb_token_log(smb_token_t *token)
+{
+	smb_win_grps_t *w_grps;
+	smb_posix_grps_t *x_grps;
+	smb_sid_attrs_t *grp;
+	char sidstr[SMB_SID_STRSZ];
+	int i;
+
+	if (token == NULL)
+		return;
+
+	syslog(LOG_DEBUG, "Token for %s\\%s",
+	    (token->tkn_domain_name) ? token->tkn_domain_name : "-NULL-",
+	    (token->tkn_account_name) ? token->tkn_account_name : "-NULL-");
+
+	syslog(LOG_DEBUG, "   User->Attr: %d",
+	    token->tkn_user->i_sidattr.attrs);
+	smb_sid_tostr((smb_sid_t *)token->tkn_user->i_sidattr.sid, sidstr);
+	syslog(LOG_DEBUG, "   User->Sid: %s (id=%u)",
+	    sidstr, token->tkn_user->i_id);
+
+	smb_sid_tostr((smb_sid_t *)token->tkn_owner->i_sidattr.sid, sidstr);
+	syslog(LOG_DEBUG, "   Ownr->Sid: %s (id=%u)",
+	    sidstr, token->tkn_owner->i_id);
+
+	smb_sid_tostr((smb_sid_t *)token->tkn_primary_grp->i_sidattr.sid,
+	    sidstr);
+	syslog(LOG_DEBUG, "   PGrp->Sid: %s (id=%u)",
+	    sidstr, token->tkn_primary_grp->i_id);
+
+	w_grps = token->tkn_win_grps;
+	if (w_grps) {
+		syslog(LOG_DEBUG, "   Windows groups: %d",
+		    w_grps->wg_count);
+
+		for (i = 0; i < w_grps->wg_count; ++i) {
+			grp = &w_grps->wg_groups[i].i_sidattr;
+			syslog(LOG_DEBUG,
+			    "    Grp[%d].Attr:%d", i, grp->attrs);
+			if (w_grps->wg_groups[i].i_sidattr.sid) {
+				smb_sid_tostr((smb_sid_t *)grp->sid, sidstr);
+				syslog(LOG_DEBUG,
+				    "    Grp[%d].Sid: %s (id=%u)", i, sidstr,
+				    w_grps->wg_groups[i].i_id);
+			}
+		}
+	}
+	else
+		syslog(LOG_DEBUG, "   No Windows groups");
+
+	x_grps = token->tkn_posix_grps;
+	if (x_grps) {
+		syslog(LOG_DEBUG, "   Solaris groups: %d",
+		    x_grps->pg_ngrps);
+		for (i = 0; i < x_grps->pg_ngrps; i++)
+			syslog(LOG_DEBUG, "    %u",
+			    x_grps->pg_grps[i]);
+	}
+	else
+		syslog(LOG_DEBUG, "   No Solaris groups");
+
+	if (token->tkn_privileges)
+		smb_privset_log(token->tkn_privileges);
+	else
+		syslog(LOG_DEBUG, "   No privileges");
+}
--- a/usr/src/lib/smbsrv/libsmb/Makefile.com	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/Makefile.com	Mon Apr 14 10:40:32 2008 -0700
@@ -62,6 +62,7 @@
 	smb_lgrp.o		\
 	smb_mac.o		\
 	smb_nic.o		\
+	smb_nicmon.o		\
 	smb_pwdutil.o		\
 	smb_privilege.o		\
 	smb_scfutil.o		\
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h	Mon Apr 14 10:40:32 2008 -0700
@@ -285,7 +285,7 @@
 extern int smb_gethostname(char *, size_t, int);
 extern int smb_getfqhostname(char *, size_t);
 extern int smb_getnetbiosname(char *, size_t);
-extern nt_sid_t *smb_getdomainsid(void);
+extern smb_sid_t *smb_getdomainsid(void);
 
 extern int smb_get_nameservers(struct in_addr *, int);
 extern void smb_tonetbiosname(char *, char *, char);
@@ -573,10 +573,10 @@
 	struct nt_domain *next;
 	nt_domain_type_t type;
 	char *name;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 } nt_domain_t;
 
-nt_domain_t *nt_domain_new(nt_domain_type_t type, char *name, nt_sid_t *sid);
+nt_domain_t *nt_domain_new(nt_domain_type_t type, char *name, smb_sid_t *sid);
 void nt_domain_delete(nt_domain_t *domain);
 nt_domain_t *nt_domain_add(nt_domain_t *new_domain);
 void nt_domain_remove(nt_domain_t *domain);
@@ -585,9 +585,9 @@
 char *nt_domain_xlat_type(nt_domain_type_t domain_type);
 nt_domain_type_t nt_domain_xlat_type_name(char *type_name);
 nt_domain_t *nt_domain_lookup_name(char *domain_name);
-nt_domain_t *nt_domain_lookup_sid(nt_sid_t *domain_sid);
+nt_domain_t *nt_domain_lookup_sid(smb_sid_t *domain_sid);
 nt_domain_t *nt_domain_lookupbytype(nt_domain_type_t type);
-nt_sid_t *nt_domain_local_sid(void);
+smb_sid_t *nt_domain_local_sid(void);
 
 typedef enum {
 	SMB_LGRP_BUILTIN = 1,
@@ -595,7 +595,7 @@
 } smb_gdomain_t;
 
 typedef struct smb_gsid {
-	nt_sid_t *gs_sid;
+	smb_sid_t *gs_sid;
 	uint16_t gs_type;
 } smb_gsid_t;
 
@@ -625,20 +625,20 @@
 int smb_lgrp_getcmnt(char *, char **);
 int smb_lgrp_getpriv(char *, uint8_t, boolean_t *);
 int smb_lgrp_setpriv(char *, uint8_t, boolean_t);
-int smb_lgrp_add_member(char *, nt_sid_t *, uint16_t);
-int smb_lgrp_del_member(char *, nt_sid_t *, uint16_t);
+int smb_lgrp_add_member(char *, smb_sid_t *, uint16_t);
+int smb_lgrp_del_member(char *, smb_sid_t *, uint16_t);
 int smb_lgrp_getbyname(char *, smb_group_t *);
 int smb_lgrp_getbyrid(uint32_t, smb_gdomain_t, smb_group_t *);
 int smb_lgrp_numbydomain(smb_gdomain_t, int *);
-int smb_lgrp_numbymember(nt_sid_t *, int *);
+int smb_lgrp_numbymember(smb_sid_t *, int *);
 void smb_lgrp_free(smb_group_t *);
-boolean_t smb_lgrp_is_member(smb_group_t *, nt_sid_t *);
+boolean_t smb_lgrp_is_member(smb_group_t *, smb_sid_t *);
 char *smb_lgrp_strerror(int);
 int smb_lgrp_iteropen(smb_giter_t *);
 void smb_lgrp_iterclose(smb_giter_t *);
 int smb_lgrp_iterate(smb_giter_t *, smb_group_t *);
 
-int smb_lookup_sid(nt_sid_t *, char *buf, int buflen);
+int smb_lookup_sid(smb_sid_t *, char *buf, int buflen);
 int smb_lookup_name(char *, smb_gsid_t *);
 
 #define	SMB_LGRP_SUCCESS		0
@@ -717,6 +717,10 @@
 int smb_nic_getnext(smb_niciter_t *);
 boolean_t smb_nic_exists(uint32_t, boolean_t);
 
+/* NIC Monitoring functions */
+int smb_nicmon_start(const char *);
+void smb_nicmon_stop(void);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers	Mon Apr 14 10:40:32 2008 -0700
@@ -84,15 +84,6 @@
 	mts_wctomb;
 	netr_client_mkabsolute;
 	netr_client_xfree;
-	nt_builtin_findfirst;
-	nt_builtin_findnext;
-	nt_builtin_fini;
-	nt_builtin_init;
-	nt_builtin_is_wellknown;
-	nt_builtin_lookup;
-	nt_builtin_lookup_domain;
-	nt_builtin_lookup_name;
-	nt_builtin_lookup_sid;
 	nt_domain_add;
 	nt_domain_flush;
 	nt_domain_init;
@@ -101,22 +92,6 @@
 	nt_domain_lookup_sid;
 	nt_domain_lookupbytype;
 	nt_domain_new;
-	nt_sid_dup;
-	nt_sid_format2;
-	nt_sid_format;
-	nt_sid_gen_null_sid;
-	nt_sid_get_rid;
-	nt_sid_is_builtin;
-	nt_sid_is_equal;
-	nt_sid_is_indomain;
-	nt_sid_is_local;
-	nt_sid_is_valid;
-	nt_sid_length;
-	nt_sid_logf;
-	nt_sid_name_use;
-	nt_sid_splice;
-	nt_sid_split;
-	nt_sid_strtosid;
 	oem_get_smb_cpid;
 	oem_get_telnet_cpid;
 	oem_language_set;
@@ -258,6 +233,8 @@
 	smb_nic_getnext;
 	smb_nic_getnum;
 	smb_nic_init;
+	smb_nicmon_start;
+	smb_nicmon_stop;
 	smb_priv_getbyname;
 	smb_priv_getbyvalue;
 	smb_priv_presentable_ids;
@@ -284,6 +261,19 @@
 	smb_resolve_netbiosname;
 	smb_setdomaininfo;
 	smb_setdomainprops;
+	smb_sid_cmp;
+	smb_sid_dup;
+	smb_sid_free;
+	smb_sid_fromstr;
+	smb_sid_getrid;
+	smb_sid_indomain;
+	smb_sid_islocal;
+	smb_sid_isvalid;
+	smb_sid_len;
+	smb_sid_splice;
+	smb_sid_split;
+	smb_sid_tostr;
+	smb_sid_type2str;
 	smb_smf_create_service_pgroup;
 	smb_smf_end_transaction;
 	smb_smf_get_boolean_property;
@@ -297,9 +287,7 @@
 	smb_smf_set_opaque_property;
 	smb_smf_set_string_property;
 	smb_smf_start_transaction;
-	smb_token_log;
 	smb_token_mkselfrel;
-	smb_token_print;
 	smb_token_query_privilege;
 	smb_trace;
 	smb_tracef;
@@ -309,6 +297,13 @@
 	smb_wins_exclude_list;
 	smb_wins_iplist;
 	smb_wins_is_excluded;
+	smb_wka_fini;
+	smb_wka_init;
+	smb_wka_is_wellknown;
+	smb_wka_lookup;
+	smb_wka_lookup_domain;
+	smb_wka_lookup_name;
+	smb_wka_lookup_sid;
 	smbnative_lm_value;
 	smbnative_os_value;
 	smbnative_pdc_value;
--- a/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c	Mon Apr 14 10:40:32 2008 -0700
@@ -94,12 +94,12 @@
 }
 
 int
-smb_lookup_sid(nt_sid_t *sid, char *sidbuf, int sidbuflen)
+smb_lookup_sid(smb_sid_t *sid, char *sidbuf, int sidbuflen)
 {
 	char *buf, *rbufp;
 	size_t buflen, rbufsize;
 	int opcode = SMB_DR_LOOKUP_SID;
-	char strsid[NT_SID_FMTBUF_SIZE];
+	char strsid[SMB_SID_STRSZ];
 	char *name = NULL;
 	int fd;
 
@@ -109,7 +109,7 @@
 		return (NT_STATUS_INVALID_PARAMETER);
 	}
 
-	if (!nt_sid_is_valid(sid)) {
+	if (!smb_sid_isvalid(sid)) {
 		syslog(LOG_ERR, "%s: invalid SID",
 		    smbapi_desc[opcode]);
 		return (NT_STATUS_INVALID_SID);
@@ -119,7 +119,7 @@
 		return (NT_STATUS_INTERNAL_ERROR);
 
 	/* Encode */
-	nt_sid_format2(sid, strsid);
+	smb_sid_tostr(sid, strsid);
 	if ((buf = smb_dr_encode_string(opcode, strsid, &buflen)) == 0) {
 		syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
 		(void) close(fd);
@@ -144,7 +144,7 @@
 	(void) close(fd);
 
 	if ((name == NULL) || (*name == '\0'))
-		nt_sid_format2(sid, sidbuf);
+		smb_sid_tostr(sid, sidbuf);
 
 	(void) strlcpy(sidbuf, name, sidbuflen);
 	xdr_free(xdr_string, (char *)&name);
@@ -202,7 +202,7 @@
 
 	*p++ = '\0';
 	sid->gs_type = atoi(strsid);
-	sid->gs_sid = nt_sid_strtosid(p);
+	sid->gs_sid = smb_sid_fromstr(p);
 	xdr_free(xdr_string, (char *)&strsid);
 	return (NT_STATUS_SUCCESS);
 }
--- a/usr/src/lib/smbsrv/libsmb/common/smb_auth.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_auth.c	Mon Apr 14 10:40:32 2008 -0700
@@ -27,7 +27,6 @@
 
 #include <strings.h>
 #include <stdlib.h>
-#include <smbsrv/alloc.h>
 #include <smbsrv/codepage.h>
 #include <smbsrv/oem.h>
 #include <smbsrv/ctype.h>
--- a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c	Mon Apr 14 10:40:32 2008 -0700
@@ -39,8 +39,7 @@
 
 #include <smbsrv/smbinfo.h>
 #include <smbsrv/string.h>
-#include <smbsrv/ntsid.h>
-#include <smbsrv/alloc.h>
+#include <smbsrv/smb_sid.h>
 
 #include <smbsrv/libsmb.h>
 
@@ -77,7 +76,7 @@
 nt_domain_init(char *resource_domain, uint32_t secmode)
 {
 	nt_domain_t *domain;
-	nt_sid_t *sid = NULL;
+	smb_sid_t *sid = NULL;
 	char sidstr[128];
 	char *lsidstr;
 	char hostname[MAXHOSTNAMELEN];
@@ -94,7 +93,7 @@
 	lsidstr = smb_config_get_localsid();
 
 	if (lsidstr) {
-		sid = nt_sid_strtosid(lsidstr);
+		sid = smb_sid_fromstr(lsidstr);
 
 		if (sid) {
 			domain = nt_domain_new(NT_DOMAIN_LOCAL, hostname, sid);
@@ -107,7 +106,7 @@
 		return (SMB_DOMAIN_NOMACHINE_SID);
 	}
 
-	if ((sid = nt_sid_strtosid(NT_BUILTIN_DOMAIN_SIDSTR)) != NULL) {
+	if ((sid = smb_sid_fromstr(NT_BUILTIN_DOMAIN_SIDSTR)) != NULL) {
 		domain = nt_domain_new(NT_DOMAIN_BUILTIN, "BUILTIN", sid);
 		(void) nt_domain_add(domain);
 		free(sid);
@@ -116,8 +115,8 @@
 	if (secmode == SMB_SECMODE_DOMAIN) {
 		rc = smb_config_getstr(SMB_CI_DOMAIN_SID, sidstr,
 		    sizeof (sidstr));
-		sid = (rc == SMBD_SMF_OK) ? nt_sid_strtosid(sidstr) : NULL;
-		if (nt_sid_is_valid(sid)) {
+		sid = (rc == SMBD_SMF_OK) ? smb_sid_fromstr(sidstr) : NULL;
+		if (smb_sid_isvalid(sid)) {
 			domain = nt_domain_new(NT_DOMAIN_PRIMARY,
 			    resource_domain, sid);
 			(void) nt_domain_add(domain);
@@ -140,7 +139,7 @@
  * the new domain structure is returned. Otherwise a null pointer is returned.
  */
 nt_domain_t *
-nt_domain_new(nt_domain_type_t type, char *name, nt_sid_t *sid)
+nt_domain_new(nt_domain_type_t type, char *name, smb_sid_t *sid)
 {
 	nt_domain_t *new_domain;
 
@@ -156,7 +155,7 @@
 	bzero(new_domain, sizeof (nt_domain_t));
 	new_domain->type = type;
 	new_domain->name = strdup(name);
-	new_domain->sid = nt_sid_dup(sid);
+	new_domain->sid = smb_sid_dup(sid);
 
 	return (new_domain);
 }
@@ -188,7 +187,7 @@
 nt_domain_t *
 nt_domain_add(nt_domain_t *new_domain)
 {
-	char *sidstr;
+	char sidstr[SMB_SID_STRSZ];
 
 	if (new_domain == NULL)
 		return (NULL);
@@ -199,9 +198,8 @@
 	nt_domain_list = new_domain;
 
 	if (new_domain->type == NT_DOMAIN_PRIMARY) {
-		sidstr = nt_sid_format(new_domain->sid);
+		smb_sid_tostr(new_domain->sid, sidstr);
 		(void) smb_config_setstr(SMB_CI_DOMAIN_SID, sidstr);
-		free(sidstr);
 	}
 	(void) rw_unlock(&nt_domain_lock);
 
@@ -312,13 +310,13 @@
  * a pointer to it is returned. Otherwise a null pointer is returned.
  */
 nt_domain_t *
-nt_domain_lookup_sid(nt_sid_t *domain_sid)
+nt_domain_lookup_sid(smb_sid_t *domain_sid)
 {
 	nt_domain_t *domain = nt_domain_list;
 
 	(void) rw_rdlock(&nt_domain_lock);
 	while (domain) {
-		if (nt_sid_is_equal(domain->sid, domain_sid))
+		if (smb_sid_cmp(domain->sid, domain_sid))
 			break;
 
 		domain = domain->next;
@@ -360,7 +358,7 @@
  * represents the local domain, which is named after the local hostname.
  * The local domain SID must exist.
  */
-nt_sid_t *
+smb_sid_t *
 nt_domain_local_sid(void)
 {
 	nt_domain_t *domain = nt_domain_list;
--- a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c	Mon Apr 14 10:40:32 2008 -0700
@@ -94,7 +94,7 @@
  * Tries to get a mapping for the given uid/gid
  */
 idmap_stat
-smb_idmap_getsid(uid_t id, int idtype, nt_sid_t **sid)
+smb_idmap_getsid(uid_t id, int idtype, smb_sid_t **sid)
 {
 	smb_idmap_batch_t sib;
 	idmap_stat stat;
@@ -118,7 +118,7 @@
 		return (stat);
 	}
 
-	*sid = nt_sid_dup(sib.sib_maps[0].sim_sid);
+	*sid = smb_sid_dup(sib.sib_maps[0].sim_sid);
 
 	smb_idmap_batch_destroy(&sib);
 
@@ -131,7 +131,7 @@
  * Tries to get a mapping for the given SID
  */
 idmap_stat
-smb_idmap_getid(nt_sid_t *sid, uid_t *id, int *id_type)
+smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *id_type)
 {
 	smb_idmap_batch_t sib;
 	smb_idmap_t *sim;
@@ -199,10 +199,9 @@
 void
 smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
 {
-	nt_sid_t *sid;
 	int i;
 
-	if (!sib)
+	if (sib == NULL)
 		return;
 
 	if (sib->sib_idmaph) {
@@ -210,7 +209,7 @@
 		sib->sib_idmaph = NULL;
 	}
 
-	if (!sib->sib_maps)
+	if (sib->sib_maps == NULL)
 		return;
 
 	if (sib->sib_flags & SMB_IDMAP_ID2SID) {
@@ -218,11 +217,8 @@
 		 * SIDs are allocated only when mapping
 		 * UID/GID to SIDs
 		 */
-		for (i = 0; i < sib->sib_nmap; i++) {
-			sid = sib->sib_maps[i].sim_sid;
-			if (sid)
-				free(sid);
-		}
+		for (i = 0; i < sib->sib_nmap; i++)
+			smb_sid_free(sib->sib_maps[i].sim_sid);
 	}
 
 	if (sib->sib_size && sib->sib_maps) {
@@ -244,26 +240,28 @@
  */
 idmap_stat
 smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
-    nt_sid_t *sid, int idtype)
+    smb_sid_t *sid, int idtype)
 {
-	nt_sid_t *tmpsid;
+	char sidstr[SMB_SID_STRSZ];
+	smb_sid_t *tmpsid;
 	idmap_stat stat;
 	int flag = 0;
 
 	if (!idmaph || !sim || !sid)
 		return (IDMAP_ERR_ARG);
 
-	tmpsid = nt_sid_dup(sid);
+	tmpsid = smb_sid_dup(sid);
 	if (!tmpsid)
 		return (IDMAP_ERR_MEMORY);
 
-	if (nt_sid_split(tmpsid, &sim->sim_rid) != 0) {
-		free(tmpsid);
+	if (smb_sid_split(tmpsid, &sim->sim_rid) != 0) {
+		smb_sid_free(tmpsid);
 		return (IDMAP_ERR_ARG);
 	}
 
-	sim->sim_domsid = nt_sid_format(tmpsid);
-	free(tmpsid);
+	smb_sid_tostr(tmpsid, sidstr);
+	sim->sim_domsid = sidstr;
+	smb_sid_free(tmpsid);
 
 	switch (idtype) {
 	case SMB_IDMAP_USER:
@@ -283,11 +281,9 @@
 		break;
 
 	default:
-		free(sim->sim_domsid);
 		return (IDMAP_ERR_ARG);
 	}
 
-	free(sim->sim_domsid);
 	return (stat);
 }
 
@@ -380,7 +376,7 @@
 static int
 smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
 {
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	smb_idmap_t *sim;
 	int i;
 
@@ -393,12 +389,12 @@
 		if (sim->sim_domsid == NULL)
 			return (-1);
 
-		sid = nt_sid_strtosid(sim->sim_domsid);
+		sid = smb_sid_fromstr(sim->sim_domsid);
 		free(sim->sim_domsid);
 		if (sid == NULL)
 			return (-1);
 
-		sim->sim_sid = nt_sid_splice(sid, sim->sim_rid);
+		sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
 		free(sid);
 	}
 
--- a/usr/src/lib/smbsrv/libsmb/common/smb_info.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_info.c	Mon Apr 14 10:40:32 2008 -0700
@@ -310,11 +310,11 @@
  *
  * Note: Callers are responsible for freeing a returned SID.
  */
-nt_sid_t *
+smb_sid_t *
 smb_getdomainsid(void)
 {
 	char buf[MAXHOSTNAMELEN];
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	int security_mode;
 	int rc;
 
@@ -327,7 +327,7 @@
 	if ((rc != SMBD_SMF_OK) || (*buf == '\0'))
 		return (NULL);
 
-	if ((sid = nt_sid_strtosid(buf)) == NULL)
+	if ((sid = smb_sid_fromstr(buf)) == NULL)
 		return (NULL);
 
 	return (sid);
--- a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c	Mon Apr 14 10:40:32 2008 -0700
@@ -144,7 +144,7 @@
 } smb_lgplist_t;
 
 static mutex_t smb_lgrp_lsid_mtx;
-static nt_sid_t *smb_lgrp_lsid;
+static smb_sid_t *smb_lgrp_lsid;
 
 static int smb_lgrp_db_init(void);
 static sqlite *smb_lgrp_db_open(int);
@@ -161,9 +161,9 @@
 static int smb_lgrp_gtbl_count(sqlite *, int, int *);
 
 static int smb_lgrp_dtbl_insert(sqlite *, char *, uint32_t *);
-static int smb_lgrp_dtbl_getidx(sqlite *, nt_sid_t *, uint16_t,
+static int smb_lgrp_dtbl_getidx(sqlite *, smb_sid_t *, uint16_t,
     uint32_t *, uint32_t *);
-static int smb_lgrp_dtbl_getsid(sqlite *, uint32_t, nt_sid_t **);
+static int smb_lgrp_dtbl_getsid(sqlite *, uint32_t, smb_sid_t **);
 
 static int smb_lgrp_mlist_add(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
 static int smb_lgrp_mlist_del(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
@@ -180,7 +180,7 @@
 static void smb_lgrp_set_default_privs(smb_group_t *);
 static boolean_t smb_lgrp_chkname(char *);
 static boolean_t smb_lgrp_chkmember(uint16_t);
-static int smb_lgrp_getsid(int, uint32_t *, uint16_t, sqlite *, nt_sid_t **);
+static int smb_lgrp_getsid(int, uint32_t *, uint16_t, sqlite *, smb_sid_t **);
 
 /*
  * smb_lgrp_add
@@ -197,10 +197,10 @@
 int
 smb_lgrp_add(char *gname, char *cmnt)
 {
-	well_known_account_t *wk_acct;
+	smb_wka_t *wka;
 	struct group *pxgrp;
 	smb_group_t grp;
-	nt_sid_t *sid = NULL;
+	smb_sid_t *sid = NULL;
 	sqlite *db;
 	int rc;
 
@@ -215,8 +215,8 @@
 	grp.sg_name = utf8_strlwr(gname);
 	grp.sg_cmnt = cmnt;
 
-	wk_acct = nt_builtin_lookup(gname);
-	if (wk_acct == NULL) {
+	wka = smb_wka_lookup(gname);
+	if (wka == NULL) {
 		if ((pxgrp = getgrnam(gname)) == NULL)
 			return (SMB_LGRP_NOT_FOUND);
 
@@ -227,7 +227,7 @@
 		    != IDMAP_SUCCESS)
 			return (SMB_LGRP_NO_SID);
 
-		if (!nt_sid_is_indomain(smb_lgrp_lsid, sid)) {
+		if (!smb_sid_indomain(smb_lgrp_lsid, sid)) {
 			free(sid);
 			return (SMB_LGRP_SID_NOTLOCAL);
 		}
@@ -236,15 +236,15 @@
 		grp.sg_domain = SMB_LGRP_LOCAL;
 		grp.sg_rid = pxgrp->gr_gid;
 	} else {
-		if (wk_acct->flags & LGF_HIDDEN) {
+		if ((wka->wka_flags & SMB_WKAFLG_LGRP_ENABLE) == 0) {
 			/* cannot add well-known accounts */
 			return (SMB_LGRP_WKSID);
 		}
 
-		grp.sg_id.gs_type = wk_acct->sid_name_use;
-		if ((sid = nt_sid_strtosid(wk_acct->sid)) == NULL)
+		grp.sg_id.gs_type = wka->wka_type;
+		if ((sid = smb_sid_fromstr(wka->wka_sid)) == NULL)
 			return (SMB_LGRP_NO_MEMORY);
-		(void) nt_sid_get_rid(sid, &grp.sg_rid);
+		(void) smb_sid_getrid(sid, &grp.sg_rid);
 		free(sid);
 		grp.sg_domain = SMB_LGRP_BUILTIN;
 
@@ -288,11 +288,11 @@
 		return (SMB_LGRP_SUCCESS);
 
 	/* Cannot rename well-known groups */
-	if (nt_builtin_is_wellknown(gname))
+	if (smb_wka_is_wellknown(gname))
 		return (SMB_LGRP_WKSID);
 
 	/* Cannot rename to a well-known groups */
-	if (nt_builtin_is_wellknown(new_gname))
+	if (smb_wka_is_wellknown(new_gname))
 		return (SMB_LGRP_WKSID);
 
 	grp.sg_name = new_gname;
@@ -320,7 +320,7 @@
 		return (SMB_LGRP_INVALID_NAME);
 
 	/* Cannot remove a built-in group */
-	if (nt_builtin_is_wellknown(gname))
+	if (smb_wka_is_wellknown(gname))
 		return (SMB_LGRP_WKSID);
 
 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
@@ -463,7 +463,7 @@
  * Add the given account to the specified group as its member.
  */
 int
-smb_lgrp_add_member(char *gname, nt_sid_t *msid, uint16_t sid_type)
+smb_lgrp_add_member(char *gname, smb_sid_t *msid, uint16_t sid_type)
 {
 	sqlite *db;
 	smb_gsid_t mid;
@@ -473,7 +473,7 @@
 	if (!smb_lgrp_chkname(gname))
 		return (SMB_LGRP_INVALID_NAME);
 
-	if (!nt_sid_is_valid(msid))
+	if (!smb_sid_isvalid(msid))
 		return (SMB_LGRP_INVALID_ARG);
 
 	if (!smb_lgrp_chkmember(sid_type))
@@ -495,7 +495,7 @@
  * Delete the specified member from the given group.
  */
 int
-smb_lgrp_del_member(char *gname, nt_sid_t *msid, uint16_t sid_type)
+smb_lgrp_del_member(char *gname, smb_sid_t *msid, uint16_t sid_type)
 {
 	sqlite *db;
 	smb_gsid_t mid;
@@ -505,7 +505,7 @@
 	if (!smb_lgrp_chkname(gname))
 		return (SMB_LGRP_INVALID_NAME);
 
-	if (!nt_sid_is_valid(msid))
+	if (!smb_sid_isvalid(msid))
 		return (SMB_LGRP_INVALID_ARG);
 
 	mid.gs_sid = msid;
@@ -624,7 +624,7 @@
  * as a member.
  */
 int
-smb_lgrp_numbymember(nt_sid_t *msid, int *count)
+smb_lgrp_numbymember(smb_sid_t *msid, int *count)
 {
 	smb_giter_t gi;
 	smb_group_t grp;
@@ -661,11 +661,11 @@
 
 	free(grp->sg_name);
 	free(grp->sg_cmnt);
-	free(grp->sg_id.gs_sid);
+	smb_sid_free(grp->sg_id.gs_sid);
 	smb_privset_free(grp->sg_privs);
 
 	for (i = 0; i < grp->sg_nmembers; i++)
-		free(grp->sg_members[i].gs_sid);
+		smb_sid_free(grp->sg_members[i].gs_sid);
 	free(grp->sg_members);
 }
 
@@ -781,7 +781,7 @@
  * the given group.
  */
 boolean_t
-smb_lgrp_is_member(smb_group_t *grp, nt_sid_t *sid)
+smb_lgrp_is_member(smb_group_t *grp, smb_sid_t *sid)
 {
 	int i;
 
@@ -789,7 +789,7 @@
 		return (B_FALSE);
 
 	for (i = 0; i < grp->sg_nmembers; i++) {
-		if (nt_sid_is_equal(grp->sg_members[i].gs_sid, sid))
+		if (smb_sid_cmp(grp->sg_members[i].gs_sid, sid))
 			return (B_TRUE);
 	}
 
@@ -822,7 +822,8 @@
 	case SMB_LGRP_NO_LOCAL_SID:
 		return (dgettext(TEXT_DOMAIN, "cannot get the machine SID"));
 	case SMB_LGRP_SID_NOTLOCAL:
-		return (dgettext(TEXT_DOMAIN, "not a local SID"));
+		return (dgettext(TEXT_DOMAIN,
+		    "got a non-local SID for a local account"));
 	case SMB_LGRP_WKSID:
 		return (dgettext(TEXT_DOMAIN,
 		    "operation not permitted on well-known accounts"));
@@ -901,7 +902,7 @@
 {
 	char *supported_bg[] =
 	    {"Administrators", "Backup Operators", "Power Users"};
-	well_known_account_t *wka;
+	smb_wka_t *wka;
 	int rc, i, ngrp;
 	char *lsid_str;
 
@@ -913,9 +914,9 @@
 		return (SMB_LGRP_NO_LOCAL_SID);
 	}
 
-	smb_lgrp_lsid = nt_sid_strtosid(lsid_str);
+	smb_lgrp_lsid = smb_sid_fromstr(lsid_str);
 	free(lsid_str);
-	if (!nt_sid_is_valid(smb_lgrp_lsid)) {
+	if (!smb_sid_isvalid(smb_lgrp_lsid)) {
 		free(smb_lgrp_lsid);
 		smb_lgrp_lsid = NULL;
 		(void) mutex_unlock(&smb_lgrp_lsid_mtx);
@@ -933,12 +934,12 @@
 
 	ngrp = sizeof (supported_bg) / sizeof (supported_bg[0]);
 	for (i = 0; i < ngrp; i++) {
-		wka = nt_builtin_lookup(supported_bg[i]);
+		wka = smb_wka_lookup(supported_bg[i]);
 		if (wka == NULL)
 			continue;
-		rc = smb_lgrp_add(wka->name, wka->desc);
+		rc = smb_lgrp_add(wka->wka_name, wka->wka_desc);
 		if (rc != SMB_LGRP_SUCCESS)
-			syslog(LOG_DEBUG, "failed to add %s", wka->name);
+			syslog(LOG_DEBUG, "failed to add %s", wka->wka_name);
 	}
 
 	return (SMB_LGRP_SUCCESS);
@@ -1601,18 +1602,18 @@
  * it in the domain table as a new SID.
  */
 static int
-smb_lgrp_dtbl_getidx(sqlite *db, nt_sid_t *sid, uint16_t sid_type,
+smb_lgrp_dtbl_getidx(sqlite *db, smb_sid_t *sid, uint16_t sid_type,
     uint32_t *dom_idx, uint32_t *rid)
 {
-	char sidstr[NT_SID_FMTBUF_SIZE];
-	nt_sid_t *dom_sid;
+	char sidstr[SMB_SID_STRSZ];
+	smb_sid_t *dom_sid;
 	char **result;
 	int nrow, ncol;
 	char *errmsg = NULL;
 	char *sql;
 	int rc;
 
-	if (nt_sid_is_indomain(smb_lgrp_lsid, sid)) {
+	if (smb_sid_indomain(smb_lgrp_lsid, sid)) {
 		/* This is a local SID */
 		int id_type = (sid_type == SidTypeUser)
 		    ? SMB_IDMAP_USER : SMB_IDMAP_GROUP;
@@ -1623,12 +1624,12 @@
 		return (SMB_LGRP_SUCCESS);
 	}
 
-	dom_sid = nt_sid_dup(sid);
+	dom_sid = smb_sid_dup(sid);
 	if (dom_sid == NULL)
 		return (SMB_LGRP_NO_MEMORY);
 
-	(void) nt_sid_split(dom_sid, rid);
-	nt_sid_format2(dom_sid, sidstr);
+	(void) smb_sid_split(dom_sid, rid);
+	smb_sid_tostr(dom_sid, sidstr);
 	free(dom_sid);
 
 	sql = sqlite_mprintf("SELECT dom_idx FROM domains WHERE dom_sid = '%s'",
@@ -1672,7 +1673,7 @@
  * Caller must free the returned SID by calling free().
  */
 static int
-smb_lgrp_dtbl_getsid(sqlite *db, uint32_t dom_idx, nt_sid_t **sid)
+smb_lgrp_dtbl_getsid(sqlite *db, uint32_t dom_idx, smb_sid_t **sid)
 {
 	char **result;
 	int nrow, ncol;
@@ -1701,7 +1702,7 @@
 		break;
 
 	case 1:
-		*sid = nt_sid_strtosid(result[1]);
+		*sid = smb_sid_fromstr(result[1]);
 		rc = (*sid == NULL)
 		    ? SMB_LGRP_INTERNAL_ERROR : SMB_LGRP_SUCCESS;
 		break;
@@ -2010,47 +2011,59 @@
  * smb_lgrp_decode_members
  *
  * Decodes the members information read from group table
- * (nmembers, members) into a binray format specified by the
+ * (nmembers, members) into a binary format specified by the
  * member fields of smb_group_t
  */
 static int
 smb_lgrp_decode_members(smb_group_t *grp, char *nmembers, char *members,
     sqlite *db)
 {
+	smb_lgmid_t *m_id;
 	smb_lgmid_t *m_ids;
-	smb_lgmid_t *mid;
-	smb_gsid_t *member;
+	smb_gsid_t *m_sid;
+	smb_gsid_t *m_sids;
+	int m_num;
 	int mids_size;
 	int i, rc;
 
-	grp->sg_nmembers = atoi(nmembers);
-	mids_size = grp->sg_nmembers * sizeof (smb_lgmid_t);
-	m_ids = malloc(mids_size);
-	if (m_ids == NULL)
+	grp->sg_nmembers = 0;
+	grp->sg_members = NULL;
+
+	m_num = atoi(nmembers);
+	mids_size = m_num * sizeof (smb_lgmid_t);
+	if ((m_ids = malloc(mids_size)) == NULL)
 		return (SMB_LGRP_NO_MEMORY);
 
-	grp->sg_members = malloc(grp->sg_nmembers * sizeof (smb_gsid_t));
-	if (grp->sg_members == NULL) {
+	m_sids = malloc(m_num * sizeof (smb_gsid_t));
+	if (m_sids == NULL) {
 		free(m_ids);
 		return (SMB_LGRP_NO_MEMORY);
 	}
+	bzero(m_sids, m_num * sizeof (smb_gsid_t));
 
 	(void) hextobin(members, strlen(members), (char *)m_ids, mids_size);
 
-	mid = m_ids;
-	member = grp->sg_members;
-	for (i = 0; i < grp->sg_nmembers; i++, mid++, member++) {
-		rc = smb_lgrp_getsid(mid->m_idx, &mid->m_rid, mid->m_type, db,
-		    &member->gs_sid);
+	m_id = m_ids;
+	m_sid = m_sids;
+	for (i = 0; i < m_num; i++, m_id++, m_sid++) {
+		rc = smb_lgrp_getsid(m_id->m_idx, &m_id->m_rid, m_id->m_type,
+		    db, &m_sid->gs_sid);
+
 		if (rc != SMB_LGRP_SUCCESS) {
 			free(m_ids);
-			return (SMB_LGRP_DB_ERROR);
+			for (m_sid = m_sids; m_sid->gs_sid != NULL; m_sid++)
+				smb_sid_free(m_sid->gs_sid);
+			free(m_sids);
+			return (rc);
 		}
 
-		member->gs_type = mid->m_type;
+		m_sid->gs_type = m_id->m_type;
 	}
 
 	free(m_ids);
+
+	grp->sg_nmembers = m_num;
+	grp->sg_members = m_sids;
 	return (SMB_LGRP_SUCCESS);
 }
 
@@ -2194,10 +2207,10 @@
  */
 static int
 smb_lgrp_getsid(int dom_idx, uint32_t *rid, uint16_t sid_type,
-    sqlite *db, nt_sid_t **sid)
+    sqlite *db, smb_sid_t **sid)
 {
-	nt_sid_t *dom_sid = NULL;
-	nt_sid_t *res_sid = NULL;
+	smb_sid_t *dom_sid = NULL;
+	smb_sid_t *res_sid = NULL;
 	int id_type;
 	int rc;
 
@@ -2211,12 +2224,12 @@
 		/*
 		 * Make sure the returned SID is local
 		 */
-		if (!nt_sid_is_indomain(smb_lgrp_lsid, res_sid)) {
-			free(res_sid);
+		if (!smb_sid_indomain(smb_lgrp_lsid, res_sid)) {
+			smb_sid_free(res_sid);
 			return (SMB_LGRP_SID_NOTLOCAL);
 		}
 
-		(void) nt_sid_get_rid(res_sid, rid);
+		(void) smb_sid_getrid(res_sid, rid);
 		*sid = res_sid;
 		return (SMB_LGRP_SUCCESS);
 	}
@@ -2225,8 +2238,8 @@
 	if (rc != SMB_LGRP_SUCCESS)
 		return (SMB_LGRP_DB_ERROR);
 
-	res_sid = nt_sid_splice(dom_sid, *rid);
-	free(dom_sid);
+	res_sid = smb_sid_splice(dom_sid, *rid);
+	smb_sid_free(dom_sid);
 	if (res_sid == NULL)
 		return (SMB_LGRP_NO_MEMORY);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_nicmon.c	Mon Apr 14 10:40:32 2008 -0700
@@ -0,0 +1,263 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * This is the SMB NIC monitoring module.
+ */
+#include <sys/types.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <syslog.h>
+#include <smbsrv/libsmb.h>
+#include <smbsrv/libsmbns.h>
+
+static pthread_t smb_nicmon_thread;
+
+static void smb_nicmon_setup_rtsock(int, int *);
+static int smb_nicmon_needscan(int);
+static void *smb_nicmon_daemon(void *);
+static int smb_nicmon_setup_eventpipe(int *, int *);
+
+/* Use this to stop monitoring */
+static int eventpipe_write = -1;
+
+/* Use this to refresh service instance */
+static char *smb_nicmon_caller_fmri = NULL;
+
+/*
+ * Start the nic monitor thread.
+ */
+int
+smb_nicmon_start(const char *svc_fmri)
+{
+	int rc = 0;
+
+	if ((rc = smb_nic_init()) != 0) {
+		syslog(LOG_ERR, "NIC monitor failed to initialize (%s)",
+		    strerror(errno));
+		return (rc);
+	}
+
+	rc = pthread_create(&smb_nicmon_thread, NULL, smb_nicmon_daemon, 0);
+	if (rc != 0) {
+		syslog(LOG_ERR, "NIC monitor failed to start (%s)",
+		    strerror(errno));
+		return (rc);
+	}
+
+	if (svc_fmri)
+		smb_nicmon_caller_fmri = (char *)svc_fmri;
+
+	return (rc);
+}
+
+/*
+ * Stop the nic monitor.
+ */
+void
+smb_nicmon_stop(void)
+{
+	uchar_t buf = 1;
+
+	if (eventpipe_write < 0)
+		return;
+
+	(void) write(eventpipe_write, &buf, sizeof (buf));
+	smb_nicmon_caller_fmri = NULL;
+	smb_nic_fini();
+}
+
+/*
+ * Setup routing socket for getting RTM messages.
+ */
+static void
+smb_nicmon_setup_rtsock(int af, int *s)
+{
+	int flags;
+
+	*s = socket(PF_ROUTE, SOCK_RAW, af);
+	if (*s == -1) {
+		syslog(LOG_ERR, "smb_nicmon_daemon: failed to "
+		    "create routing socket");
+		return;
+	}
+	if ((flags = fcntl(*s, F_GETFL, 0)) < 0) {
+		syslog(LOG_ERR, "smb_nicmon_daemon: "
+		    "failed to fcntl F_GETFL");
+		(void) close(*s);
+		*s = -1;
+		return;
+	}
+	if ((fcntl(*s, F_SETFL, flags | O_NONBLOCK)) < 0) {
+		syslog(LOG_ERR, "smb_nicmon_daemon: "
+		    "failed to fcntl F_SETFL");
+		(void) close(*s);
+		*s = -1;
+		return;
+	}
+}
+
+static int
+smb_nicmon_needscan(int sock)
+{
+	int	nbytes;
+	int64_t msg[2048 / 8];
+	struct rt_msghdr *rtm;
+	int need_if_scan = 0;
+
+	/* Read as many messages as possible and try to empty the sockets */
+	for (;;) {
+		nbytes = read(sock, msg, sizeof (msg));
+		if (nbytes <= 0) {
+			break;
+		}
+		rtm = (struct rt_msghdr *)msg;
+		if (rtm->rtm_version != RTM_VERSION) {
+			continue;
+		}
+		if (nbytes < rtm->rtm_msglen) {
+			syslog(LOG_DEBUG, "smb_nicmon_daemon: short read: %d "
+			    "of %d", nbytes, rtm->rtm_msglen);
+			continue;
+		}
+
+		switch (rtm->rtm_type) {
+		case RTM_NEWADDR:
+		case RTM_DELADDR:
+		case RTM_IFINFO:
+			need_if_scan = 1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return (need_if_scan);
+}
+
+/*
+ * Create pipe for signal delivery and set up signal handlers.
+ */
+static int
+smb_nicmon_setup_eventpipe(int *read_pipe, int *write_pipe)
+{
+	int fds[2];
+
+	if ((pipe(fds)) < 0) {
+		syslog(LOG_ERR, "smb_nicmon_daemon: failed to open pipe");
+		return (1);
+	}
+	*read_pipe = fds[0];
+	*write_pipe = fds[1];
+	return (0);
+}
+
+/*ARGSUSED*/
+static void *
+smb_nicmon_daemon(void *args)
+{
+	struct pollfd pollfds[2];
+	int pollfd_num = 2;
+	int i, nic_changed;
+	/* AF_INET routing socket add AF_INET6 when we support IPv6 */
+	static int rtsock_v4;
+	static int eventpipe_read = -1;
+
+	/*
+	 * Create the global routing socket.  We use this to
+	 * monitor changes in NIC interfaces. We are only interested
+	 * in new inerface addition/deletion and change in UP/DOWN status.
+	 */
+	smb_nicmon_setup_rtsock(AF_INET, &rtsock_v4);
+	if (rtsock_v4 == -1) {
+		syslog(LOG_ERR, "smb_nicmon_daemon: "
+		    "cannot open routing socket");
+		return (NULL);
+	}
+
+	if (smb_nicmon_setup_eventpipe(&eventpipe_read, &eventpipe_write)
+	    != 0) {
+		syslog(LOG_ERR, "smb_nicmon_daemon: cannot open event pipes");
+		return (NULL);
+	}
+
+	/*
+	 * Keep listening for activity on any of the sockets.
+	 */
+	for (;;) {
+		nic_changed = 0;
+		pollfds[0].fd = rtsock_v4;
+		pollfds[0].events = POLLIN;
+		pollfds[1].fd = eventpipe_read;
+		pollfds[1].events = POLLIN;
+		if (poll(pollfds, pollfd_num, -1) < 0) {
+			if (errno == EINTR)
+				continue;
+			syslog(LOG_ERR, "smb_nicmon_daemon: "
+			    "poll failed with errno %d", errno);
+			break;
+		}
+		for (i = 0; i < pollfd_num; i++) {
+			if ((pollfds[i].fd < 0) ||
+			    !(pollfds[i].revents & POLLIN))
+				continue;
+			if (pollfds[i].fd == rtsock_v4)
+				nic_changed = smb_nicmon_needscan(rtsock_v4);
+			if (pollfds[i].fd == eventpipe_read)
+				goto done;
+		}
+
+		/*
+		 * If anything changed, do refresh the instance
+		 * of the registered SMF service.
+		 */
+		if (nic_changed && smb_nicmon_caller_fmri)
+			if (smf_refresh_instance(smb_nicmon_caller_fmri) != 0)
+				syslog(LOG_ERR, "smb_nicmon_daemon: "
+				    "failed to refresh SMF instance %s",
+				    smb_nicmon_caller_fmri);
+	}
+done:
+	/* Close sockets */
+	(void) close(rtsock_v4);
+	(void) close(eventpipe_read);
+	(void) close(eventpipe_write);
+	eventpipe_write = -1;
+	return (NULL);
+}
--- a/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c	Mon Apr 14 10:40:32 2008 -0700
@@ -40,8 +40,6 @@
 #include <uuid/uuid.h>
 #include <sys/param.h>
 
-#include <smbsrv/alloc.h>
-
 #include <smbsrv/libsmb.h>
 
 /*
--- a/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -31,11 +31,12 @@
  * BUILTIN domains, and some other miscellaneous bits.
  */
 
+#include <stdlib.h>
 #include <string.h>
 #include <synch.h>
-#include <smbsrv/ntsid.h>
+
+#include <smbsrv/smb_sid.h>
 #include <smbsrv/string.h>
-#include <smbsrv/alloc.h>
 
 /*
  * This table should contain all of the NT builtin domain names.
@@ -56,241 +57,200 @@
  * the SIDs. For each domain, ensure that the domain SID appears
  * before any aliases in that domain.
  */
-static well_known_account_t wkt[] = {
+static smb_wka_t wka_tbl[] = {
 	{ SidTypeWellKnownGroup, 0, "S-1-0-0",		"Null",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 1, "S-1-1-0",		"Everyone",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 1, "S-1-2-0",		"LOCAL",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 1, "S-1-3-0",		"CREATOR OWNER",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 1, "S-1-3-1",		"CREATOR GROUP",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 1, "S-1-3-2",		"CREATOR OWNER SERVER",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 1, "S-1-3-3",		"CREATOR GROUP SERVER",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeDomain, 1, "S-1-4",			"NON UNIQUE",
-	    LGF_HIDDEN, 0, NULL},
-	{ SidTypeDomain, 2, "S-1-5",		"NT AUTHORITY",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
+	{ SidTypeDomain, 2, "S-1-5",			"NT AUTHORITY",
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-1",		"DIALUP",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-2",		"NETWORK",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-3",		"BATCH",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-4",		"INTERACTIVE",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-6",		"SERVICE",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-7",		"ANONYMOUS",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-8",		"PROXY",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-9",		"SERVER",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-10",		"SELF",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-11",		"Authenticated Users",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-12",		"RESTRICTED",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-18",		"SYSTEM",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeWellKnownGroup, 2, "S-1-5-21",		"NON_UNIQUE",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeDomain, 2, "S-1-5-32",			"BUILTIN",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeAlias, 1, "S-1-5-32-544",		"Administrators",
-	    0, "Members can fully administer the computer/domain", NULL },
+	    SMB_WKAFLG_LGRP_ENABLE,
+	    "Members can fully administer the computer/domain", NULL },
 	{ SidTypeAlias, 1, "S-1-5-32-545",		"Users",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeAlias, 1, "S-1-5-32-546",		"Guests",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeAlias, 1, "S-1-5-32-547",		"Power Users",
-	    0, "Members can share directories", NULL },
+	    SMB_WKAFLG_LGRP_ENABLE, "Members can share directories", NULL },
 	{ SidTypeAlias, 1, "S-1-5-32-548",		"Account Operators",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeAlias, 1, "S-1-5-32-549",		"Server Operators",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeAlias, 1, "S-1-5-32-550",		"Print Operators",
-	    LGF_HIDDEN, 0, NULL},
+	    0, NULL, NULL},
 	{ SidTypeAlias, 1, "S-1-5-32-551",		"Backup Operators",
-	    0, "Members can bypass file security to back up files", NULL },
+	    SMB_WKAFLG_LGRP_ENABLE,
+	    "Members can bypass file security to back up files", NULL },
 	{ SidTypeAlias, 1, "S-1-5-32-552",		"Replicator",
-	    LGF_HIDDEN, 0, NULL}
+	    0, NULL, NULL}
 };
 
+#define	SMB_WKA_NUM	(sizeof (wka_tbl)/sizeof (wka_tbl[0]))
 
 /*
- * nt_builtin_lookup_sid
+ * smb_wka_lookup_sid
  *
- * Search the wkt looking for a match on the specified SID. If the
+ * Search the wka_tbl looking for a match on the specified SID. If the
  * SID matches a builtin entry, the associated name is returned.
  * Otherwise a null pointer is returned.
  */
 char *
-nt_builtin_lookup_sid(nt_sid_t *sid, WORD *sid_name_use)
+smb_wka_lookup_sid(smb_sid_t *sid, uint16_t *sid_name_use)
 {
-	well_known_account_t *entry;
-	char *sidbuf;
-	int sidlen;
+	smb_wka_t *entry;
 	int i;
 
-	if ((sidbuf = nt_sid_format(sid)) == 0)	{
-		return (0);
-	}
-
-	sidlen = strlen(sidbuf);
+	for (i = 0; i < SMB_WKA_NUM; ++i) {
+		entry = &wka_tbl[i];
 
-	for (i = 0; i < sizeof (wkt)/sizeof (wkt[0]); ++i) {
-		entry = &wkt[i];
-
-		if (strncmp(sidbuf, entry->sid, sidlen) == 0) {
+		if (smb_sid_cmp(sid, entry->wka_binsid)) {
 			if (sid_name_use)
-				*sid_name_use = entry->sid_name_use;
-			free(sidbuf);
-			return (entry->name);
+				*sid_name_use = entry->wka_type;
+			return (entry->wka_name);
 		}
 	}
 
-	free(sidbuf);
-	return (0);
+	return (NULL);
 }
 
 
 /*
- * nt_builtin_lookup_name
+ * smb_wka_lookup_name
  *
- * Search the wkt looking for a match on the specified name. If the
+ * Search the wka_tbl looking for a match on the specified name. If the
  * name matches a builtin entry, the associated SID (which is in
  * malloc'd memory) is returned. Otherwise a null pointer is returned.
  */
-nt_sid_t *
-nt_builtin_lookup_name(char *name, WORD *sid_name_use)
+smb_sid_t *
+smb_wka_lookup_name(char *name, uint16_t *sid_name_use)
 {
-	well_known_account_t *entry;
+	smb_wka_t *entry;
 	int i;
 
-	for (i = 0; i < sizeof (wkt)/sizeof (wkt[0]); ++i) {
-		entry = &wkt[i];
+	for (i = 0; i < SMB_WKA_NUM; ++i) {
+		entry = &wka_tbl[i];
 
-		if (!utf8_strcasecmp(name, entry->name)) {
+		if (!utf8_strcasecmp(name, entry->wka_name)) {
 			if (sid_name_use)
-				*sid_name_use = entry->sid_name_use;
-			return (nt_sid_strtosid(entry->sid));
+				*sid_name_use = entry->wka_type;
+			return (smb_sid_dup(entry->wka_binsid));
 		}
 	}
 
-	return (0);
+	return (NULL);
 }
 
 /*
- * nt_builtin_lookup
+ * smb_wka_lookup
  *
- * Search the wkt looking for a match on the specified name. If the
+ * Search the wka_tbl looking for a match on the specified name. If the
  * name matches a builtin entry then pointer to that entry will be
  * returned. Otherwise 0 is returned.
  */
-well_known_account_t *
-nt_builtin_lookup(char *name)
+smb_wka_t *
+smb_wka_lookup(char *name)
 {
-	well_known_account_t *entry;
+	smb_wka_t *entry;
 	int i;
 
 	(void) rw_rdlock(&wk_rwlock);
-	for (i = 0; i < sizeof (wkt)/sizeof (wkt[0]); ++i) {
-		entry = &wkt[i];
+	for (i = 0; i < SMB_WKA_NUM; ++i) {
+		entry = &wka_tbl[i];
 
-		if (!utf8_strcasecmp(name, entry->name)) {
+		if (!utf8_strcasecmp(name, entry->wka_name)) {
 			(void) rw_unlock(&wk_rwlock);
 			return (entry);
 		}
 	}
 
 	(void) rw_unlock(&wk_rwlock);
-	return (0);
+	return (NULL);
 }
 
 
 /*
- * nt_builtin_is_wellknown
+ * smb_wka_is_wellknown
  *
- * Search the wkt looking for a match on the specified name. If the
+ * Search the wka_tbl looking for a match on the specified name. If the
  * name matches a builtin entry returns 1. Otherwise returns 0.
  */
-int
-nt_builtin_is_wellknown(char *name)
+boolean_t
+smb_wka_is_wellknown(char *name)
 {
-	well_known_account_t *entry;
 	int i;
 
-	for (i = 0; i < sizeof (wkt)/sizeof (wkt[0]); ++i) {
-		entry = &wkt[i];
-
-		if (!utf8_strcasecmp(name, entry->name)) {
-			return (1);
-		}
+	for (i = 0; i < SMB_WKA_NUM; ++i) {
+		if (utf8_strcasecmp(name, wka_tbl[i].wka_name) == 0)
+			return (B_TRUE);
 	}
 
-	return (0);
+	return (B_FALSE);
 }
 
 /*
- * nt_builtin_lookup_domain
+ * smb_wka_lookup_domain
  *
  * Return the builtin domain name for the specified alias or group name.
  */
 char *
-nt_builtin_lookup_domain(char *name)
+smb_wka_lookup_domain(char *name)
 {
-	well_known_account_t *entry;
-	char *domain_name;
+	smb_wka_t *entry;
 	int i;
 
-	for (i = 0; i < sizeof (wkt)/sizeof (wkt[0]); ++i) {
-		entry = &wkt[i];
+	for (i = 0; i < SMB_WKA_NUM; ++i) {
+		entry = &wka_tbl[i];
 
-		if (!utf8_strcasecmp(name, entry->name)) {
-			domain_name = domain[entry->domain_ix];
-			return (domain_name);
-		}
+		if (!utf8_strcasecmp(name, entry->wka_name))
+			return (domain[entry->wka_domidx]);
 	}
 
-	return (0);
+	return (NULL);
 }
 
 /*
- * nt_builtin_findfirst
- *
- * Returns pointer to the first entry of well known sids table.
- */
-well_known_account_t *
-nt_builtin_findfirst(DWORD *iterator)
-{
-	*iterator = 1;
-	return (&wkt[0]);
-}
-
-/*
- * nt_builtin_findnext
- *
- * Returns pointer to the entry of well known sids table specified
- * by the iterator. Increments iterator to point to the next entry.
- */
-well_known_account_t *
-nt_builtin_findnext(DWORD *iterator)
-{
-	if (*iterator < sizeof (wkt)/sizeof (wkt[0]))
-		return (&wkt[(*iterator)++]);
-
-	return (0);
-}
-
-/*
- * nt_builtin_init
+ * smb_wka_init
  *
  * Generate binary SIDs from the string SIDs in the table
  * and set the proper field.
@@ -301,9 +261,9 @@
  * This function should only be called once.
  */
 int
-nt_builtin_init()
+smb_wka_init(void)
 {
-	well_known_account_t *entry;
+	smb_wka_t *entry;
 	int i;
 
 	(void) rw_wrlock(&wk_rwlock);
@@ -312,12 +272,12 @@
 		return (1);
 	}
 
-	for (i = 0; i < sizeof (wkt)/sizeof (wkt[0]); ++i) {
-		entry = &wkt[i];
-		entry->binsid = nt_sid_strtosid(entry->sid);
-		if (entry->binsid == NULL) {
+	for (i = 0; i < SMB_WKA_NUM; ++i) {
+		entry = &wka_tbl[i];
+		entry->wka_binsid = smb_sid_fromstr(entry->wka_sid);
+		if (entry->wka_binsid == NULL) {
 			(void) rw_unlock(&wk_rwlock);
-			nt_builtin_fini();
+			smb_wka_fini();
 			return (0);
 		}
 	}
@@ -328,7 +288,7 @@
 }
 
 void
-nt_builtin_fini()
+smb_wka_fini(void)
 {
 	int i;
 
@@ -338,10 +298,10 @@
 		return;
 	}
 
-	for (i = 0; i < sizeof (wkt)/sizeof (wkt[0]); ++i) {
-		if (wkt[i].binsid) {
-			free(wkt[i].binsid);
-			wkt[i].binsid = NULL;
+	for (i = 0; i < SMB_WKA_NUM; ++i) {
+		if (wka_tbl[i].wka_binsid) {
+			free(wka_tbl[i].wka_binsid);
+			wka_tbl[i].wka_binsid = NULL;
 		}
 	}
 
--- a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h	Mon Apr 14 10:40:32 2008 -0700
@@ -85,6 +85,7 @@
 extern adjoin_status_t ads_join(char *, char *, char *, char *, int);
 extern char *adjoin_report_err(adjoin_status_t);
 extern int ads_domain_change_cleanup(char *);
+extern int ads_update_attrs(void);
 
 /* DYNDNS functions */
 extern int dns_msgid_init(void);
--- a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers	Mon Apr 14 10:40:32 2008 -0700
@@ -39,6 +39,7 @@
 	ads_publish_share;
 	ads_refresh;
 	ads_remove_share;
+	ads_update_attrs;
 	dns_msgid_init;
 	dyndns_clear_rev_zone;
 	dyndns_update;
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c	Mon Apr 14 10:40:32 2008 -0700
@@ -91,8 +91,6 @@
 static ADS_HANDLE *ads_open_main(char *domain, char *user, char *password);
 static int ads_bind(ADS_HANDLE *);
 static void ads_get_computer_dn(ADS_HANDLE *, char *, size_t);
-static int ads_get_host_principals(char *fqhost, char *domain,
-    char **spn, char **upn);
 static int ads_add_computer(ADS_HANDLE *ah);
 static int ads_modify_computer(ADS_HANDLE *ah);
 static void ads_del_computer(ADS_HANDLE *ah);
@@ -104,6 +102,11 @@
 static ADS_HOST_INFO *ads_get_host_info(void);
 static void ads_set_host_info(ADS_HOST_INFO *host);
 static void ads_free_host_info(void);
+static int ads_get_spnset(char *fqhost, char **spn_set);
+static void ads_free_spnset(char **spn_set);
+static int ads_alloc_attr(LDAPMod *attrs[], int num);
+static void ads_free_attr(LDAPMod *attrs[]);
+
 
 /*
  * ads_init
@@ -983,7 +986,31 @@
 }
 
 /*
- * free_attr
+ * ads_alloc_attr
+ *
+ * Since the attrs is a null-terminated array, all elements
+ * in the array (except the last one) will point to allocated
+ * memory.
+ */
+static int
+ads_alloc_attr(LDAPMod *attrs[], int num)
+{
+	int i;
+
+	bzero(attrs, num * sizeof (LDAPMod *));
+	for (i = 0; i < (num - 1); i++) {
+		attrs[i] = (LDAPMod *)malloc(sizeof (LDAPMod));
+		if (attrs[i] == NULL) {
+			ads_free_attr(attrs);
+			return (-1);
+		}
+	}
+
+	return (0);
+}
+
+/*
+ * ads_free_attr
  * Free memory allocated when publishing a share.
  * Parameters:
  *   attrs: an array of LDAPMod pointers
@@ -991,7 +1018,7 @@
  *   None
  */
 static void
-free_attr(LDAPMod *attrs[])
+ads_free_attr(LDAPMod *attrs[])
 {
 	int i;
 	for (i = 0; attrs[i]; i++) {
@@ -1000,6 +1027,43 @@
 }
 
 /*
+ * ads_get_spnset
+ *
+ * Derives the core set of SPNs based on the FQHN.
+ * The spn_set is a null-terminated array of char pointers.
+ *
+ * Returns 0 upon success. Otherwise, returns -1.
+ */
+static int
+ads_get_spnset(char *fqhost, char **spn_set)
+{
+	int i;
+
+	bzero(spn_set, (SMBKRB5_SPN_IDX_MAX + 1) * sizeof (char *));
+	for (i = 0; i < SMBKRB5_SPN_IDX_MAX; i++) {
+		if ((spn_set[i] = smb_krb5_get_spn(i, fqhost)) == NULL) {
+			ads_free_spnset(spn_set);
+			return (-1);
+		}
+	}
+
+	return (0);
+}
+
+/*
+ * ads_free_spnset
+ *
+ * Free the memory allocated for the set of SPNs.
+ */
+static void
+ads_free_spnset(char **spn_set)
+{
+	int i;
+	for (i = 0; spn_set[i]; i++)
+		free(spn_set[i]);
+}
+
+/*
  * ads_acquire_cred
  * Called by ads_bind() to get a handle to administrative user's credential
  * stored locally on the system.  The credential is the TGT.  If the attempt at
@@ -1322,16 +1386,11 @@
 	(void) snprintf(share_dn, len, "cn=%s,%s,%s", adsShareName,
 	    adsContainer, ah->domain_dn);
 
-	for (j = 0; j < (ADS_SHARE_NUM_ATTR - 1); j++) {
-		attrs[j] = (LDAPMod *)malloc(sizeof (LDAPMod));
-		if (attrs[j] == NULL) {
-			free_attr(attrs);
-			free(share_dn);
-			return (-1);
-		}
+	if (ads_alloc_attr(attrs, ADS_SHARE_NUM_ATTR) != 0) {
+		free(share_dn);
+		return (-1);
 	}
 
-	j = 0;
 	attrs[j]->mod_op = LDAP_MOD_ADD;
 	attrs[j]->mod_type = "objectClass";
 	tmp1[0] = "top";
@@ -1347,19 +1406,17 @@
 	tmp2[1] = 0;
 	attrs[j]->mod_values = tmp2;
 
-	attrs[++j] = 0;
-
 	if ((ret = ldap_add_s(ah->ld, share_dn, attrs)) != LDAP_SUCCESS) {
 		(void) snprintf(buf, ADS_MAXMSGLEN,
 		    "ads_add_share: %s:", share_dn);
 		/* LINTED - E_SEC_PRINTF_VAR_FMT */
 		syslog(LOG_ERR, ldap_err2string(ret));
-		free_attr(attrs);
+		ads_free_attr(attrs);
 		free(share_dn);
 		return (ret);
 	}
 	free(share_dn);
-	free_attr(attrs);
+	ads_free_attr(attrs);
 
 	(void) snprintf(buf, ADS_MAXMSGLEN,
 	    "Share %s has been added to ADS container: %s.\n", adsShareName,
@@ -1695,57 +1752,6 @@
 }
 
 /*
- * ads_get_host_principals
- *
- * This function returns both the HOST Service Principal Name and User
- * Principal Name.
- *
- * If fqhost is NULL, this function will attempt to obtain fully qualified
- * hostname prior to generating the host principals. If caller is only
- * interested in getting the User Principal Name, spn argument can be
- * set to NULL.
- */
-static int
-ads_get_host_principals(char *fqhost, char *domain, char **spn,
-    char **upn)
-{
-	char hostname[MAXHOSTNAMELEN];
-	char *p;
-
-	if (spn != NULL)
-		*spn = NULL;
-
-	*upn = NULL;
-
-	if (fqhost) {
-		(void) strlcpy(hostname, fqhost, MAXHOSTNAMELEN);
-	} else {
-		if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0)
-			return (-1);
-
-		(void) snprintf(hostname, MAXHOSTNAMELEN, "%s.%s", hostname,
-		    domain);
-	}
-
-	if ((p = smb_krb5_get_spn(SMBKRB5_SPN_IDX_HOST, hostname)) == NULL) {
-		return (-1);
-	}
-
-	*upn = smb_krb5_get_upn(p, domain);
-	if (*upn == NULL) {
-		free(p);
-		return (-1);
-	}
-
-	if (spn != NULL)
-		*spn = p;
-	else
-		free(p);
-
-	return (0);
-}
-
-/*
  * ads_add_computer
  *
  * Returns 0 upon success. Otherwise, returns -1.
@@ -1772,13 +1778,13 @@
 {
 	LDAPMod *attrs[ADS_COMPUTER_NUM_ATTR];
 	char *oc_vals[6], *sam_val[2], *usr_val[2];
-	char *svc_val[2], *ctl_val[2], *fqh_val[2];
-	int j = 0;
+	char *spn_set[SMBKRB5_SPN_IDX_MAX + 1], *ctl_val[2], *fqh_val[2];
+	int j = -1;
 	int ret, usrctl_flags = 0;
 	char sam_acct[MAXHOSTNAMELEN + 1];
 	char fqhost[MAXHOSTNAMELEN];
 	char dn[ADS_DN_MAX];
-	char *user_principal, *svc_principal;
+	char *user_principal;
 	char usrctl_buf[16];
 	int max;
 
@@ -1790,27 +1796,27 @@
 	(void) snprintf(fqhost, MAXHOSTNAMELEN, "%s.%s", fqhost,
 	    ah->domain);
 
-	if (ads_get_host_principals(fqhost, ah->domain, &svc_principal,
-	    &user_principal) == -1) {
-		syslog(LOG_ERR,
-		    "ads_computer_op: unable to get host principal");
+	if (ads_get_spnset(fqhost, spn_set) != 0)
+		return (-1);
+
+	user_principal = smb_krb5_get_upn(spn_set[SMBKRB5_SPN_IDX_HOST],
+	    ah->domain);
+
+	if (user_principal == NULL) {
+		ads_free_spnset(spn_set);
 		return (-1);
 	}
 
 	ads_get_computer_dn(ah, dn, ADS_DN_MAX);
 
 	max = (ADS_COMPUTER_NUM_ATTR - ((op != LDAP_MOD_ADD) ? 1 : 0));
-	for (j = 0; j < (max - 1); j++) {
-		attrs[j] = (LDAPMod *)malloc(sizeof (LDAPMod));
-		if (attrs[j] == NULL) {
-			free_attr(attrs);
-			free(user_principal);
-			free(svc_principal);
-			return (-1);
-		}
+
+	if (ads_alloc_attr(attrs, max) != 0) {
+		free(user_principal);
+		ads_free_spnset(spn_set);
+		return (-1);
 	}
 
-	j = -1;
 	/* objectClass attribute is not modifiable. */
 	if (op == LDAP_MOD_ADD) {
 		attrs[++j]->mod_op = op;
@@ -1838,9 +1844,7 @@
 
 	attrs[++j]->mod_op = op;
 	attrs[j]->mod_type = "servicePrincipalName";
-	svc_val[0] = svc_principal;
-	svc_val[1] = 0;
-	attrs[j]->mod_values = svc_val;
+	attrs[j]->mod_values = spn_set;
 
 	attrs[++j]->mod_op = op;
 	attrs[j]->mod_type = "userAccountControl";
@@ -1858,8 +1862,6 @@
 	fqh_val[1] = 0;
 	attrs[j]->mod_values = fqh_val;
 
-	attrs[++j] = 0;
-
 	switch (op) {
 	case LDAP_MOD_ADD:
 		if ((ret = ldap_add_s(ah->ld, dn, attrs)) != LDAP_SUCCESS) {
@@ -1882,9 +1884,9 @@
 
 	}
 
-	free_attr(attrs);
+	ads_free_attr(attrs);
 	free(user_principal);
-	free(svc_principal);
+	ads_free_spnset(spn_set);
 
 	return (ret);
 }
@@ -2009,18 +2011,20 @@
 static int
 ads_update_computer_cntrl_attr(ADS_HANDLE *ah, int des_only)
 {
-	LDAPMod *attrs[6];
+	LDAPMod *attrs[2];
 	char *ctl_val[2];
-	int j = -1;
 	int ret, usrctl_flags = 0;
 	char dn[ADS_DN_MAX];
 	char usrctl_buf[16];
 
 	ads_get_computer_dn(ah, dn, ADS_DN_MAX);
 
-	attrs[++j] = (LDAPMod *) malloc(sizeof (LDAPMod));
-	attrs[j]->mod_op = LDAP_MOD_REPLACE;
-	attrs[j]->mod_type = "userAccountControl";
+
+	if (ads_alloc_attr(attrs, sizeof (attrs) / sizeof (LDAPMod *)) != 0)
+		return (-1);
+
+	attrs[0]->mod_op = LDAP_MOD_REPLACE;
+	attrs[0]->mod_type = "userAccountControl";
 
 	usrctl_flags |= (ADS_USER_ACCT_CTL_WKSTATION_TRUST_ACCT |
 	    ADS_USER_ACCT_CTL_TRUSTED_FOR_DELEGATION |
@@ -2032,9 +2036,7 @@
 	(void) snprintf(usrctl_buf, sizeof (usrctl_buf), "%d", usrctl_flags);
 	ctl_val[0] = usrctl_buf;
 	ctl_val[1] = 0;
-	attrs[j]->mod_values = ctl_val;
-
-	attrs[++j] = 0;
+	attrs[0]->mod_values = ctl_val;
 
 	if ((ret = ldap_modify_s(ah->ld, dn, attrs)) != LDAP_SUCCESS) {
 		syslog(LOG_ERR, "ads_modify_computer: %s",
@@ -2042,11 +2044,73 @@
 		ret = -1;
 	}
 
-	free_attr(attrs);
+	ads_free_attr(attrs);
 	return (ret);
 }
 
 /*
+ * ads_update_attrs
+ *
+ * Updates the servicePrincipalName and dNSHostName attributes of the
+ * system's AD computer object.
+ */
+int
+ads_update_attrs(void)
+{
+	ADS_HANDLE *ah;
+	LDAPMod *attrs[3];
+	char *fqh_val[2];
+	int i = 0;
+	int ret;
+	char fqhost[MAXHOSTNAMELEN];
+	char dn[ADS_DN_MAX];
+	char *spn_set[SMBKRB5_SPN_IDX_MAX + 1];
+
+	if ((ah = ads_open()) == NULL)
+		return (-1);
+
+	if (smb_getfqhostname(fqhost, MAXHOSTNAMELEN) != 0) {
+		ads_close(ah);
+		return (-1);
+	}
+
+	if (ads_get_spnset(fqhost, spn_set) != 0) {
+		ads_close(ah);
+		return (-1);
+	}
+
+	ads_get_computer_dn(ah, dn, ADS_DN_MAX);
+	if (ads_alloc_attr(attrs, sizeof (attrs) / sizeof (LDAPMod *)) != 0) {
+		ads_free_spnset(spn_set);
+		ads_close(ah);
+		return (-1);
+	}
+
+	attrs[i]->mod_op = LDAP_MOD_REPLACE;
+	attrs[i]->mod_type = "servicePrincipalName";
+	attrs[i]->mod_values = spn_set;
+
+	attrs[++i]->mod_op = LDAP_MOD_REPLACE;
+	attrs[i]->mod_type = "dNSHostName";
+	fqh_val[0] = fqhost;
+	fqh_val[1] = 0;
+	attrs[i]->mod_values = fqh_val;
+
+	if ((ret = ldap_modify_s(ah->ld, dn, attrs)) != LDAP_SUCCESS) {
+		syslog(LOG_ERR, "ads_update_attrs: %s",
+		    ldap_err2string(ret));
+		ret = -1;
+	}
+
+	ads_free_attr(attrs);
+	ads_free_spnset(spn_set);
+	ads_close(ah);
+
+	return (ret);
+
+}
+
+/*
  * ads_lookup_computer_attr_kvno
  *
  * Lookup the value of the Kerberos version number attribute of the computer
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c	Mon Apr 14 10:40:32 2008 -0700
@@ -1673,7 +1673,7 @@
  *                       dyndns_update calls.
  * Returns:
  *   -1: some dynamic DNS updates errors
- *    0: successful
+ *    0: successful or DDNS disabled.
  */
 int
 dyndns_update(char *fqdn, boolean_t init_msgid_counter)
@@ -1686,7 +1686,7 @@
 	char fqhn[MAXHOSTNAMELEN];
 
 	if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
-		return (-1);
+		return (0);
 
 	if (smb_gethostname(fqhn, MAXHOSTNAMELEN, 0) != 0)
 		return (-1);
@@ -1754,7 +1754,7 @@
  *   fqhn - fully-qualified hostname
  * Returns:
  *   -1: some dynamic DNS updates errors
- *    0: successful
+ *    0: successful or DDNS disabled.
  */
 int
 dyndns_clear_rev_zone(char *fqdn)
@@ -1767,7 +1767,7 @@
 	char fqhn[MAXHOSTNAMELEN];
 
 	if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
-		return (-1);
+		return (0);
 
 	if (smb_gethostname(fqhn, MAXHOSTNAMELEN, 0) != 0)
 		return (-1);
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c	Mon Apr 14 10:40:32 2008 -0700
@@ -336,7 +336,7 @@
 {
 	smb_msgbuf_t mb;
 	nt_domain_t *ntdp;
-	nt_sid_t *domain_sid;
+	smb_sid_t *domain_sid;
 	unsigned domain_sid_len;
 	char *username;
 	unsigned char buffer[MAX_DATAGRAM_LENGTH];
@@ -354,8 +354,7 @@
 	}
 
 	domain_sid = ntdp->sid;
-	domain_sid_len = nt_sid_length(domain_sid);
-	nt_sid_logf(domain_sid);
+	domain_sid_len = smb_sid_len(domain_sid);
 
 	if (smb_gethostname(hostname, MAXHOSTNAMELEN, 1) != 0)
 		return;
--- a/usr/src/pkgdefs/etc/exception_list_i386	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/pkgdefs/etc/exception_list_i386	Mon Apr 14 10:40:32 2008 -0700
@@ -979,7 +979,6 @@
 usr/include/smbsrv/nterror.h		i386
 usr/include/smbsrv/ntifs.h		i386
 usr/include/smbsrv/ntlocale.h		i386
-usr/include/smbsrv/ntsid.h		i386
 usr/include/smbsrv/ntstatus.h		i386
 usr/include/smbsrv/oem.h		i386
 usr/include/smbsrv/samlib.h		i386
@@ -993,8 +992,10 @@
 usr/include/smbsrv/smb_incl.h		i386
 usr/include/smbsrv/smb_ioctl.h		i386
 usr/include/smbsrv/smb_kproto.h		i386
+usr/include/smbsrv/smb_kstat.h		i386
 usr/include/smbsrv/smb_ktypes.h		i386
 usr/include/smbsrv/smb_privilege.h	i386
+usr/include/smbsrv/smb_sid.h		i386
 usr/include/smbsrv/smb_token.h		i386
 usr/include/smbsrv/smb_vops.h		i386
 usr/include/smbsrv/smb_winpipe.h	i386
--- a/usr/src/pkgdefs/etc/exception_list_sparc	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/pkgdefs/etc/exception_list_sparc	Mon Apr 14 10:40:32 2008 -0700
@@ -1065,7 +1065,6 @@
 usr/include/smbsrv/nterror.h		sparc
 usr/include/smbsrv/ntifs.h		sparc
 usr/include/smbsrv/ntlocale.h		sparc
-usr/include/smbsrv/ntsid.h		sparc
 usr/include/smbsrv/ntstatus.h		sparc
 usr/include/smbsrv/oem.h		sparc
 usr/include/smbsrv/samlib.h		sparc
@@ -1079,8 +1078,10 @@
 usr/include/smbsrv/smb_incl.h		sparc
 usr/include/smbsrv/smb_ioctl.h		sparc
 usr/include/smbsrv/smb_kproto.h		sparc
+usr/include/smbsrv/smb_kstat.h		sparc
 usr/include/smbsrv/smb_ktypes.h		sparc
 usr/include/smbsrv/smb_privilege.h	sparc
+usr/include/smbsrv/smb_sid.h		sparc
 usr/include/smbsrv/smb_token.h		sparc
 usr/include/smbsrv/smb_vops.h		sparc
 usr/include/smbsrv/smb_winpipe.h	sparc
--- a/usr/src/uts/common/fs/smbsrv/smb_acl.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_acl.c	Mon Apr 14 10:40:32 2008 -0700
@@ -27,7 +27,7 @@
 
 #include <sys/acl.h>
 #include <acl/acl_common.h>
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 #include <smbsrv/smb_fsops.h>
 #include <smbsrv/smb_idmap.h>
 #include <smbsrv/smb_kproto.h>
@@ -72,7 +72,7 @@
 /*
  * SID for Everyone group: S-1-1-0.
  */
-nt_sid_t everyone_sid = {
+smb_sid_t everyone_sid = {
 	NT_SID_REVISION,
 	1,
 	NT_SECURITY_WORLD_AUTH,
@@ -139,9 +139,8 @@
 	if (acl == NULL)
 		return;
 
-	for (i = 0; i < acl->sl_acecnt; i++) {
-		MEM_FREE("smbsrv", acl->sl_aces[i].se_sid);
-	}
+	for (i = 0; i < acl->sl_acecnt; i++)
+		smb_sid_free(acl->sl_aces[i].se_sid);
 
 	while ((ace = list_head(&acl->sl_sorted)) != NULL)
 		list_remove(&acl->sl_sorted, ace);
@@ -338,7 +337,7 @@
 		ace->se_hdr.se_type = zace->a_type;
 		ace->se_hdr.se_flags = smb_ace_flags_fromzfs(zace->a_flags);
 		ace->se_mask = zace->a_access_mask;
-		ace->se_sid = nt_sid_dup(sim->sim_sid);
+		ace->se_sid = smb_sid_dup(sim->sim_sid);
 		ace->se_hdr.se_bsize = smb_ace_len(ace);
 
 		acl->sl_bsize += ace->se_hdr.se_bsize;
@@ -405,7 +404,7 @@
 		zace->a_flags = smb_ace_flags_tozfs(ace->se_hdr.se_flags,
 		    isdir);
 
-		if (nt_sid_is_equal(ace->se_sid, &everyone_sid))
+		if (smb_sid_cmp(ace->se_sid, &everyone_sid))
 			zace->a_flags |= ACE_EVERYONE;
 		else {
 			sim->sim_id = &zace->a_who;
@@ -1191,7 +1190,7 @@
 		return (0);
 
 	return (SMB_ACE_HDRSIZE + sizeof (ace->se_mask) +
-	    nt_sid_length(ace->se_sid));
+	    smb_sid_len(ace->se_sid));
 }
 
 static void
@@ -1313,11 +1312,11 @@
 		return (B_FALSE);
 
 	if (smb_ace_is_generic(ace->se_hdr.se_type)) {
-		if (nt_sid_is_valid(ace->se_sid) == 0)
+		if (!smb_sid_isvalid(ace->se_sid))
 			return (B_FALSE);
 
 		min_len += sizeof (ace->se_mask);
-		min_len += nt_sid_length(ace->se_sid);
+		min_len += smb_sid_len(ace->se_sid);
 
 		if (ace->se_hdr.se_bsize < min_len)
 			return (B_FALSE);
--- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c	Mon Apr 14 10:40:32 2008 -0700
@@ -395,6 +395,19 @@
 	uniq_fid = SMB_UNIQ_FID();
 
 	if (op->fqi.last_comp_was_found) {
+
+		if ((op->fqi.last_attr.sa_vattr.va_type != VREG) &&
+		    (op->fqi.last_attr.sa_vattr.va_type != VDIR) &&
+		    (op->fqi.last_attr.sa_vattr.va_type != VLNK)) {
+
+			smb_node_release(op->fqi.last_snode);
+			smb_node_release(op->fqi.dir_snode);
+			SMB_NULL_FQI_NODES(op->fqi);
+			smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
+			    ERRnoaccess);
+			return (NT_STATUS_ACCESS_DENIED);
+		}
+
 		node = op->fqi.last_snode;
 		dnode = op->fqi.dir_snode;
 
@@ -655,24 +668,9 @@
 			    S_IWUSR | S_IWGRP | S_IWOTH;
 			new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
 
-			/*
-			 * A problem with setting the readonly bit at
-			 * create time is that this bit will prevent
-			 * writes to the file from the same fid (which
-			 * should be allowed).
-			 *
-			 * The solution is to set the bit at close time.
-			 * Meanwhile, to prevent racing opens from being
-			 * able to write to the file, the bit is set at
-			 * create time until share reservations can be set
-			 * to prevent write and delete access.  At that point,
-			 * the bit can be turned off until close (so as to
-			 * allow writes from the same fid to the file).
-			 */
-
-			if (op->dattr & SMB_FA_READONLY) {
-				new_attr.sa_dosattr = FILE_ATTRIBUTE_READONLY;
-				new_attr.sa_mask |= SMB_AT_DOSATTR;
+			if (op->dsize) {
+				new_attr.sa_vattr.va_size = op->dsize;
+				new_attr.sa_mask |= SMB_AT_SIZE;
 			}
 
 			rc = smb_fsop_create(sr, sr->user_cr, dnode,
@@ -687,10 +685,21 @@
 				return (sr->smb_error.status);
 			}
 
-			if (op->dattr & SMB_FA_READONLY) {
+			/*
+			 * A problem with setting the readonly bit at
+			 * create time is that this bit will prevent
+			 * writes to the file from the same fid (which
+			 * should be allowed).
+			 *
+			 * The solution is to set the bit at close time.
+			 * Meanwhile, to prevent racing opens from being
+			 * able to write to the file, set share reservations
+			 * to prevent write and delete access.
+			 */
+
+			if (op->dattr & SMB_FA_READONLY)
 				share_access &= ~(FILE_SHARE_WRITE |
 				    FILE_SHARE_DELETE);
-			}
 
 			node = op->fqi.last_snode;
 
@@ -707,41 +716,7 @@
 				return (status);
 			}
 
-			new_attr = op->fqi.last_attr;
-			new_attr.sa_mask = 0;
-
-			if (op->dattr & SMB_FA_READONLY) {
-				new_attr.sa_dosattr &= ~FILE_ATTRIBUTE_READONLY;
-				new_attr.sa_mask |= SMB_AT_DOSATTR;
-			}
-
-			if (op->dsize) {
-				new_attr.sa_vattr.va_size = op->dsize;
-				new_attr.sa_mask |= SMB_AT_SIZE;
-			}
-
-			if (new_attr.sa_mask) {
-				node->attr = new_attr;
-				node->what = new_attr.sa_mask;
-				rc = smb_sync_fsattr(sr, sr->user_cr, node);
-
-				if (rc != 0) {
-					smb_fsop_unshrlock(sr->user_cr, node,
-					    uniq_fid);
-
-					rw_exit(&node->n_share_lock);
-					smb_node_release(node);
-					(void) smb_fsop_remove(sr, sr->user_cr,
-					    dnode, op->fqi.last_comp, 0);
-					smb_rwx_rwexit(&dnode->n_lock);
-					smb_node_release(dnode);
-					SMB_NULL_FQI_NODES(op->fqi);
-					smbsr_errno(sr, rc);
-					return (sr->smb_error.status);
-				} else {
-					op->fqi.last_attr = node->attr;
-				}
-			}
+			op->fqi.last_attr = node->attr;
 
 		} else {
 			op->dattr |= SMB_FA_DIRECTORY;
@@ -767,24 +742,6 @@
 		op->action_taken = SMB_OACT_CREATED;
 	}
 
-	if ((op->fqi.last_attr.sa_vattr.va_type != VREG) &&
-	    (op->fqi.last_attr.sa_vattr.va_type != VDIR) &&
-	    (op->fqi.last_attr.sa_vattr.va_type != VLNK)) {
-		/* not allowed to do this */
-
-		smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
-
-		SMB_DEL_NEWOBJ(op->fqi);
-		rw_exit(&node->n_share_lock);
-		smb_node_release(node);
-		if (created)
-			smb_rwx_rwexit(&dnode->n_lock);
-		smb_node_release(dnode);
-		SMB_NULL_FQI_NODES(op->fqi);
-		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
-		return (NT_STATUS_ACCESS_DENIED);
-	}
-
 	if (max_requested) {
 		smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
 		op->desired_access |= max_allowed;
@@ -864,15 +821,10 @@
 		/*
 		 * Clients may set the DOS readonly bit on create but they
 		 * expect subsequent write operations on the open fid to
-		 * succeed.  Thus the DOS readonly bit is not set permanently
-		 * until the file is closed.  The NODE_CREATED_READONLY flag
+		 * succeed.  Thus the DOS readonly bit is not set until
+		 * the file is closed.  The NODE_CREATED_READONLY flag
 		 * will act as the indicator to set the DOS readonly bit on
 		 * close.
-		 *	Above, the readonly bit is set on create, share
-		 * reservations are set, and then the bit is unset.
-		 * These actions allow writes to the open fid to succeed
-		 * until the file is closed while preventing write access
-		 * from other opens while this fid is active.
 		 */
 		if (op->dattr & SMB_FA_READONLY) {
 			node->flags |= NODE_CREATED_READONLY;
--- a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c	Mon Apr 14 10:40:32 2008 -0700
@@ -732,39 +732,35 @@
 static int
 smb_emit_SHARE_INFO_0(struct mbuf_chain *output, unsigned char *name)
 {
-	mts_wchar_t *unibuf;
-	char *tmpbuf;
 	unsigned int cpid = oem_get_smb_cpid();
 	unsigned int length;
-	char	name_buf[MAX_SHARE_NAME_LEN];
+	char name_buf[MAX_SHARE_NAME_LEN];
+	mts_wchar_t *unibuf;
+	char *tmpbuf;
+	int rc = 0;
 
-	if (name == 0)
-		tmpbuf = "";
-	else
-		tmpbuf = (char *)name;
+	tmpbuf = (name == NULL) ? "" : (char *)name;
+	length = strlen(tmpbuf) + 1;
 
-	length = strlen(tmpbuf) + 1;
-	unibuf = MEM_MALLOC("smb", length * sizeof (mts_wchar_t));
+	unibuf = kmem_alloc(length * sizeof (mts_wchar_t), KM_SLEEP);
+	(void) mts_mbstowcs(unibuf, tmpbuf, length);
 
-	(void) mts_mbstowcs(unibuf, tmpbuf, length);
-	tmpbuf = MEM_MALLOC("smb", length);
+	tmpbuf = kmem_alloc(length, KM_SLEEP);
 	if (unicodestooems(tmpbuf, unibuf, length, cpid) == 0)
 		(void) strcpy(tmpbuf, (char *)name);
 
-	if (strlen(tmpbuf) + 1 > MAX_SHARE_NAME_LEN) {
-		MEM_FREE("smb", unibuf);
-		MEM_FREE("smb", tmpbuf);
-		return (-1);
+	if (strlen(tmpbuf) + 1 <= MAX_SHARE_NAME_LEN) {
+		bzero(name_buf, sizeof (name_buf));
+		(void) strcpy(name_buf, tmpbuf);
+		(void) smb_encode_mbc(output, "13c", name_buf);
+	} else {
+		rc = -1;
 	}
 
-	bzero(name_buf, sizeof (name_buf));
-	(void) strcpy(name_buf, tmpbuf);
-	(void) smb_encode_mbc(output, "13c", name_buf);
+	kmem_free(unibuf, length * sizeof (mts_wchar_t));
+	kmem_free(tmpbuf, length);
 
-	MEM_FREE("smb", unibuf);
-	MEM_FREE("smb", tmpbuf);
-
-	return (0);
+	return (rc);
 }
 
 static int
@@ -813,36 +809,31 @@
  * The function returns 1 for long share names and 0 when the length
  * is Ok.
  */
-static int
+static boolean_t
 is_long_sharename(unsigned char *name)
 {
+	unsigned int cpid = oem_get_smb_cpid();
+	size_t length;
 	mts_wchar_t *unibuf;
 	char *tmpbuf;
-	unsigned int cpid = oem_get_smb_cpid();
-	unsigned int length;
+	boolean_t islong;
+
+	tmpbuf = (name == NULL) ? "" : (char *)name;
+	length = strlen(tmpbuf) + 1;
 
-	if (name == 0)
-		tmpbuf = "";
-	else
-		tmpbuf = (char *)name;
+	unibuf = kmem_alloc(length * sizeof (mts_wchar_t), KM_SLEEP);
+	(void) mts_mbstowcs(unibuf, tmpbuf, length);
 
-	length = strlen(tmpbuf) + 1;
-	unibuf = MEM_MALLOC("smb", length * sizeof (mts_wchar_t));
-	(void) mts_mbstowcs(unibuf, tmpbuf, length);
-	tmpbuf = MEM_MALLOC("smb", length);
+	tmpbuf = kmem_alloc(length, KM_SLEEP);
 	if (unicodestooems(tmpbuf, unibuf, length, cpid) == 0)
 		(void) strcpy(tmpbuf, (char *)name);
 
-	if (strlen(tmpbuf) + 1 > MAX_SHARE_NAME_LEN) {
-		MEM_FREE("smb", unibuf);
-		MEM_FREE("smb", tmpbuf);
-		return (1);
-	}
+	islong = (strlen(tmpbuf) + 1 > MAX_SHARE_NAME_LEN);
 
-	MEM_FREE("smb", unibuf);
-	MEM_FREE("smb", tmpbuf);
+	kmem_free(unibuf, length * sizeof (mts_wchar_t));
+	kmem_free(tmpbuf, length);
 
-	return (0);
+	return (islong);
 }
 
 /*
@@ -950,7 +941,7 @@
 
 	do_add = (lmshrd_getinfo(dhdl, username, si) == NERR_Success) &&
 	    (si->mode & LMSHRM_TRANS) &&
-	    (is_long_sharename((unsigned char *)(si->share_name)) == 0);
+	    (!is_long_sharename((unsigned char *)(si->share_name)));
 
 	return (do_add);
 }
@@ -1245,6 +1236,7 @@
 	int cmnt_len;
 	struct mbuf_chain reply;
 	smb_user_t *user;
+	size_t cmnt_size;
 
 	user = sr->uid_user;
 	ASSERT(user);
@@ -1287,7 +1279,8 @@
 	shares_scnt = (shr_enum_info.sei_count > max_shares_per_packet)
 	    ? max_shares_per_packet : shr_enum_info.sei_count;
 
-	cmnt_str = MEM_MALLOC("smb", shr_enum_info.sei_cmntlen * sizeof (char));
+	cmnt_size = shr_enum_info.sei_cmntlen * sizeof (char);
+	cmnt_str = kmem_alloc(cmnt_size, KM_SLEEP);
 	cmnt_len = 0;
 	/* save start of buffer to free it at the end of function */
 	cmnt_start = cmnt_str;
@@ -1295,7 +1288,7 @@
 	iterator = lmshrd_open_iterator(dhdl, LMSHRM_ALL);
 
 	if (iterator == NULL) {
-		MEM_FREE("smb", cmnt_str);
+		kmem_free(cmnt_start, cmnt_size);
 		return (SDRC_DROP_VC);
 	}
 
@@ -1433,7 +1426,7 @@
 	}
 
 	(void) lmshrd_close_iterator(dhdl, iterator);
-	MEM_FREE("smb", cmnt_start);
+	kmem_free(cmnt_start, cmnt_size);
 	return (SDRC_NO_REPLY);
 }
 
--- a/usr/src/uts/common/fs/smbsrv/smb_common_tree.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_tree.c	Mon Apr 14 10:40:32 2008 -0700
@@ -183,7 +183,7 @@
 	uint16_t		access = SMB_TREE_READ_WRITE;
 	int			rc;
 	lmshare_info_t 		si;
-	nt_sid_t		*sid;
+	smb_sid_t		*sid;
 	fsvol_attr_t		vol_attr;
 	smb_attr_t		attr;
 	int			is_admin;
@@ -245,13 +245,13 @@
 	}
 
 	if (is_admin) {
-		sid = nt_sid_strtosid(ADMINISTRATORS_SID);
+		sid = smb_sid_fromstr(ADMINISTRATORS_SID);
 		if (sid) {
 			rc = smb_cred_is_member(u_cred, sid);
-			MEM_FREE("smbsrv", sid);
+			smb_sid_free(sid);
 			if (rc == 0) {
-				(void) strlcpy(errmsg,
-				    "not administrator", SMB_TREE_EMSZ);
+				(void) strlcpy(errmsg, "not administrator",
+				    SMB_TREE_EMSZ);
 				return (ERRaccess);
 			}
 		}
--- a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c	Mon Apr 14 10:40:32 2008 -0700
@@ -141,6 +141,7 @@
  */
 
 #include <smbsrv/smb_incl.h>
+#include <smbsrv/smb_kstat.h>
 #include <sys/sdt.h>
 
 #define	SMB_ALL_DISPATCH_STAT_INCR(stat)	atomic_inc_64(&stat);
@@ -1286,7 +1287,8 @@
 			ks_ndata++;
 	}
 
-	smb_dispatch_ksp = kstat_create("smb", 0, "smb_dispatch_all", "misc",
+	smb_dispatch_ksp = kstat_create(SMBSRV_KSTAT_MODULE, 0,
+	    SMBSRV_KSTAT_NAME_CMDS, SMBSRV_KSTAT_CLASS,
 	    KSTAT_TYPE_NAMED, ks_ndata, 0);
 
 	if (smb_dispatch_ksp) {
--- a/usr/src/uts/common/fs/smbsrv/smb_find.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_find.c	Mon Apr 14 10:40:32 2008 -0700
@@ -270,11 +270,12 @@
 
 	(void) smb_encode_mbc(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
 
-	pc = MEM_ZALLOC("smb", sizeof (*pc));
+	pc = kmem_zalloc(sizeof (smb_odir_context_t), KM_SLEEP);
 	pc->dc_cookie = cookie;
 	count = 0;
-	node = (struct smb_node *)0;
+	node = NULL;
 	rc = 0;
+
 	while (count < maxcount) {
 		if ((rc = smb_rdir_next(sr, &node, pc)) != 0)
 			break;
@@ -286,10 +287,11 @@
 		    (int32_t)smb_node_get_size(node, &pc->dc_attr),
 		    (*pc->dc_shortname) ? pc->dc_shortname : pc->dc_name);
 		smb_node_release(node);
-		node = (struct smb_node *)0;
+		node = NULL;
 		count++;
 	}
-	MEM_FREE("smb", pc);
+
+	kmem_free(pc, sizeof (smb_odir_context_t));
 
 	if ((rc != 0) && (rc != ENOENT)) {
 		/* returned error by smb_rdir_next() */
--- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c	Mon Apr 14 10:40:32 2008 -0700
@@ -43,8 +43,6 @@
 static int smb_fsop_sdinherit(smb_request_t *sr, smb_node_t *dnode,
     smb_fssd_t *fs_sd);
 
-static callb_cpr_t *smb_fsop_frlock_callback(flk_cb_when_t when, void *error);
-
 /*
  * The smb_fsop_* functions have knowledge of CIFS semantics.
  *
@@ -1349,7 +1347,7 @@
 
 	if (rc) {
 		smb_node_end_crit(snode);
-		return (rc);
+		return (ERANGE);
 	}
 	rc = smb_vop_read(snode->vp, uio, cr);
 
@@ -1437,7 +1435,7 @@
 
 	if (rc) {
 		smb_node_end_crit(snode);
-		return (rc);
+		return (ERANGE);
 	}
 	rc = smb_vop_write(snode->vp, uio, flag, lcount, cr);
 
@@ -2527,68 +2525,3 @@
 
 	(void) smb_vop_unshrlock(node->vp, uniq_fid, cr);
 }
-
-/*
- * smb_fsop_frlock_callback
- *
- * smb wrapper function for fs_frlock
- * this should never happen, as we are not attempting
- * to set Mandatory Locks, cmd = F_SETLK_NBMAND
- *
- */
-
-static callb_cpr_t *
-/* ARGSUSED */
-smb_fsop_frlock_callback(flk_cb_when_t when, void *error)
-{
-	return (0);
-}
-
-/*
- * smb_fs_frlock
- *
- * smb wrapper function for fs_frlock
- */
-
-int
-smb_fsop_frlock(smb_request_t *sr, smb_node_t *node, smb_lock_t *lock,
-    boolean_t unlock)
-{
-	vnode_t		*vp;
-	flock64_t	bf;
-	cred_t		*cr;
-	int		cmd;
-	flk_callback_t	flk_cb;
-	offset_t	offset = 0;
-	int		flag;
-	int		error;
-	int		i;
-
-	flk_init_callback(&flk_cb, smb_fsop_frlock_callback, &error);
-	cr = sr->user_cr;
-	vp = node->vp;
-	cmd = F_SETLK;
-
-	if (unlock == B_TRUE) {
-		bf.l_type = F_UNLCK;
-		flag = 0;
-	} else if (lock->l_type == SMB_LOCK_TYPE_READONLY) {
-		bf.l_type = F_RDLCK;
-		flag = FREAD;
-	} else if (lock->l_type == SMB_LOCK_TYPE_READWRITE) {
-		bf.l_type = F_WRLCK;
-		flag = FWRITE;
-	}
-
-	bf.l_start = lock->l_start;
-	bf.l_len = lock->l_length;
-	bf.l_whence = 0;  /* SEEK_SET */
-	bf.l_pid = lock->l_pid;
-	bf.l_sysid = 0;
-
-	for (i = 0; i < 4; i++)
-		bf.l_pad[i] = 0;
-
-	error = fs_frlock(vp, cmd, &bf, flag, offset, &flk_cb, cr, &smb_ct);
-	return (error);
-}
--- a/usr/src/uts/common/fs/smbsrv/smb_kdoor_clnt.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_kdoor_clnt.c	Mon Apr 14 10:40:32 2008 -0700
@@ -31,7 +31,6 @@
 #include <sys/sunddi.h>
 #include <sys/cmn_err.h>
 #include <sys/door.h>
-#include <smbsrv/alloc.h>
 #include <smbsrv/smb_door_svc.h>
 #include <smbsrv/smb_common_door.h>
 
--- a/usr/src/uts/common/fs/smbsrv/smb_kdoor_ops.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_kdoor_ops.c	Mon Apr 14 10:40:32 2008 -0700
@@ -34,7 +34,6 @@
 #include <smbsrv/smb_common_door.h>
 #include <smbsrv/smb_door_svc.h>
 #include <smbsrv/smb_xdr.h>
-#include <smbsrv/alloc.h>
 #include <smbsrv/smb_incl.h>
 
 /* SMB kernel module's door operation table */
--- a/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c	Mon Apr 14 10:40:32 2008 -0700
@@ -99,8 +99,8 @@
 	 * set to be exclusive, lock type is passed as
 	 * normal lock (write lock).
 	 */
-	result = smb_lock_range(sr, sr->fid_ofile,
-	    (u_offset_t)off, (uint64_t)count,  0, SMB_LOCK_TYPE_READWRITE);
+	result = smb_lock_range(sr, (u_offset_t)off, (uint64_t)count,  0,
+	    SMB_LOCK_TYPE_READWRITE);
 	if (result != NT_STATUS_SUCCESS) {
 		smb_lock_range_error(sr, result);
 		return (SDRC_ERROR);
--- a/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c	Mon Apr 14 10:40:32 2008 -0700
@@ -40,312 +40,21 @@
 
 extern caller_context_t smb_ct;
 
-static void
-smb_unlock_to_posix_unlock(smb_request_t *sr, smb_node_t *node,
-    smb_lock_t *lock, boolean_t unlock);
-
-static boolean_t
-smb_is_range_unlocked(uint64_t start, uint64_t end, smb_llist_t *llist_head,
-    uint64_t *new_mark);
-
-static int
-smb_lock_range_overlap(struct smb_lock *lock, uint64_t start, uint64_t length);
-
-static uint32_t smb_lock_range_lckrules(struct smb_request *sr,
-    smb_ofile_t *file, struct smb_node *node, smb_lock_t *dlock,
-    smb_lock_t **clockp);
-
-static uint32_t
-smb_lock_wait(struct smb_request *sr, smb_lock_t *b_lock, smb_lock_t *c_lock);
-
-static uint32_t
-smb_lock_range_ulckrules(struct smb_request *sr,
-    struct smb_node *node,
-    uint64_t start,
-    uint64_t length,
-    struct smb_lock **nodelock);
-
-static smb_lock_t *smb_lock_create(smb_request_t *sr,
-    uint64_t start, uint64_t length, uint32_t locktype, uint32_t timeout);
-static void smb_lock_destroy(smb_lock_t *lock);
-static void smb_lock_free(smb_lock_t *lock);
-
-/*
- * smb_lock_range_overlap
- *
- * Checks if lock range(start, length) overlaps
- * range in lock structure.
- *
- * return values:
- *	0 - Lock range doesn't overlap
- *	1 - Lock range overlaps.
- */
-
-#define	RANGE_NO_OVERLAP	0
-#define	RANGE_OVERLAP		1
-
-static int
-smb_lock_range_overlap(struct smb_lock *lock, uint64_t start, uint64_t length)
-{
-	/* A zero-length range doesn't overlap anything */
-	if (length == 0 || lock->l_length == 0)
-		return (RANGE_NO_OVERLAP);
-
-	if (start < lock->l_start) {
-		if (start + length > lock->l_start)
-			return (RANGE_OVERLAP);
-	} else if (start < lock->l_start + lock->l_length)
-		return (RANGE_OVERLAP);
-
-	if (start + length > lock->l_start + lock->l_length) {
-		if (start < lock->l_start + lock->l_length)
-			return (RANGE_OVERLAP);
-	} else if (start + length > lock->l_start)
-		return (RANGE_OVERLAP);
-
-	/* Lock range doen't overlap */
-	return (RANGE_NO_OVERLAP);
-}
-
-/*
- * smb_lock_range_lckrules
- *
- * Lock range rules:
- *	1. Overlapping read locks are allowed if the
- *	   current locks in the region are only read locks
- *	   irrespective of pid of smb client issuing lock request.
- *
- *	2. Read lock in the overlapped region of write lock
- *	   are allowed if the pervious lock is performed by the
- *	   same pid and connection.
- *
- * return status:
- *	NT_STATUS_SUCCESS - Input lock range adapts to lock rules.
- *	NT_STATUS_LOCK_NOT_GRANTED - Input lock conflicts lock rules.
- *	NT_STATUS_CANCELLED - Error in processing lock rules
- */
-static uint32_t
-smb_lock_range_lckrules(
-    struct smb_request	*sr,
-    smb_ofile_t		*file,
-    struct smb_node	*node,
-    smb_lock_t		*dlock,
-    smb_lock_t		**clockp)
-{
-	smb_lock_t	*lock;
-	uint32_t	status = NT_STATUS_SUCCESS;
-
-	/* Check if file is closed */
-	if (!smb_ofile_is_open(file)) {
-		return (NT_STATUS_RANGE_NOT_LOCKED);
-	}
-
-	/* Caller must hold lock for node->n_lock_list */
-	for (lock = smb_llist_head(&node->n_lock_list);
-	    lock != NULL;
-	    lock = smb_llist_next(&node->n_lock_list, lock)) {
-
-		if (!smb_lock_range_overlap(lock, dlock->l_start,
-		    dlock->l_length))
-			continue;
-
-		/*
-		 * Check to see if lock in the overlapping record
-		 * is only read lock. Current finding is read
-		 * locks can overlapped irrespective of pids.
-		 */
-		if ((lock->l_type == SMB_LOCK_TYPE_READONLY) &&
-		    (dlock->l_type == SMB_LOCK_TYPE_READONLY)) {
-			continue;
-		}
-
-		/*
-		 * When the read lock overlaps write lock, check if
-		 * allowed.
-		 */
-		if ((dlock->l_type == SMB_LOCK_TYPE_READONLY) &&
-		    !(lock->l_type == SMB_LOCK_TYPE_READONLY)) {
-			if (lock->l_file == sr->fid_ofile &&
-			    lock->l_session_kid == sr->session->s_kid &&
-			    lock->l_pid == sr->smb_pid &&
-			    lock->l_uid == sr->smb_uid) {
-				continue;
-			}
-		}
-
-		/* Conflict in overlapping lock element */
-		*clockp = lock;
-		status = NT_STATUS_LOCK_NOT_GRANTED;
-		break;
-	}
-
-	return (status);
-}
+static void smb_lock_posix_unlock(smb_node_t *, smb_lock_t *, cred_t *);
+static boolean_t smb_is_range_unlocked(uint64_t, uint64_t, smb_llist_t *,
+    uint64_t *);
+static int smb_lock_range_overlap(smb_lock_t *, uint64_t, uint64_t);
+static uint32_t smb_lock_range_lckrules(smb_request_t *, smb_ofile_t *,
+    smb_node_t *, smb_lock_t *, smb_lock_t **);
+static clock_t smb_lock_wait(smb_request_t *, smb_lock_t *, smb_lock_t *);
+static uint32_t smb_lock_range_ulckrules(smb_request_t *, smb_node_t *,
+    uint64_t, uint64_t, smb_lock_t **nodelock);
+static smb_lock_t *smb_lock_create(smb_request_t *, uint64_t, uint64_t,
+    uint32_t, uint32_t);
+static void smb_lock_destroy(smb_lock_t *);
+static void smb_lock_free(smb_lock_t *);
+static int smb_lock_frlock(vnode_t *, smb_lock_t *, boolean_t, cred_t *);
 
-/*
- * smb_lock_wait
- *
- * Wait operation for smb overlapping lock to be released.  Caller must hold
- * write lock for node->n_lock_list so that the set of active locks can't
- * change unexpectedly.  The lock for node->n_lock_list  will be released
- * within this function during the sleep after the lock dependency has
- * been recorded.
- *
- * return value
- *
- *	NT_STATUS_CANCELLED		Error occurred during wait operation
- *	NT_STATUS_SUCCESS		Wait completed.
- */
-static uint32_t
-smb_lock_wait(smb_request_t *sr, smb_lock_t *b_lock, smb_lock_t *c_lock)
-{
-	clock_t		result;
-	uint32_t	status = NT_STATUS_SUCCESS;
-
-	ASSERT(sr->sr_awaiting == NULL);
-
-	mutex_enter(&sr->sr_mutex);
-
-	switch (sr->sr_state) {
-	case SMB_REQ_STATE_ACTIVE:
-		/*
-		 * Wait up till the timeout time keeping track of actual
-		 * time waited for possible retry failure.
-		 */
-		sr->sr_state = SMB_REQ_STATE_WAITING_LOCK;
-		sr->sr_awaiting = c_lock;
-		mutex_exit(&sr->sr_mutex);
-
-		mutex_enter(&c_lock->l_mutex);
-		/*
-		 * The conflict list (l_conflict_list) for a lock contains
-		 * all the locks that are blocked by and in conflict with
-		 * that lock.  Add the new lock to the conflict list for the
-		 * active lock.
-		 *
-		 * l_conflict_list is currently a fancy way of representing
-		 * the references/dependencies on a lock.  It could be
-		 * replaced with a reference count but this approach
-		 * has the advantage that MDB can display the lock
-		 * dependencies at any point in time.  In the future
-		 * we should be able to leverage the list to implement
-		 * an asynchronous locking model.
-		 *
-		 * l_blocked_by is the reverse of the conflict list.  It
-		 * points to the lock that the new lock conflicts with.
-		 * As currently implemented this value is purely for
-		 * debug purposes -- there are windows of time when
-		 * l_blocked_by may be non-NULL even though there is no
-		 * conflict list
-		 */
-		b_lock->l_blocked_by = c_lock;
-		smb_slist_insert_tail(&c_lock->l_conflict_list, b_lock);
-		smb_llist_exit(&c_lock->l_file->f_node->n_lock_list);
-
-		/*
-		 * XXX Hack.. drop s_lock to avoid blocking subsequent SMBs
-		 * that might affect the state of this lock (i.e.
-		 * smb_com_close).  We shouldn't sleep while holding
-		 * locks anyway.
-		 */
-		smb_rwx_rwexit(&sr->session->s_lock);
-
-		if (SMB_LOCK_INDEFINITE_WAIT(b_lock)) {
-			cv_wait(&c_lock->l_cv, &c_lock->l_mutex);
-		} else {
-			result = cv_timedwait(&c_lock->l_cv,
-			    &c_lock->l_mutex, b_lock->l_end_time);
-			if (result == -1) {
-				status = NT_STATUS_CANCELLED;
-			}
-		}
-
-		/*
-		 * XXX Hack continued from above... re-acquire s_lock
-		 * OK to hardcode RW_READER since this is just a hack and
-		 * we really should yank it out and do something else.
-		 */
-		smb_rwx_rwenter(&sr->session->s_lock, RW_READER);
-
-		mutex_exit(&c_lock->l_mutex);
-
-		smb_llist_enter(&c_lock->l_file->f_node->n_lock_list,
-		    RW_WRITER);
-		smb_slist_remove(&c_lock->l_conflict_list, b_lock);
-
-		mutex_enter(&sr->sr_mutex);
-		sr->sr_awaiting = NULL;
-		if (sr->sr_state == SMB_REQ_STATE_CANCELED) {
-			status = NT_STATUS_CANCELLED;
-		} else {
-			sr->sr_state = SMB_REQ_STATE_ACTIVE;
-		}
-		break;
-
-	case SMB_REQ_STATE_CANCELED:
-		status = NT_STATUS_CANCELLED;
-		mutex_exit(&sr->sr_mutex);
-		break;
-
-	default:
-		ASSERT(0);
-		break;
-	}
-
-	mutex_exit(&sr->sr_mutex);
-
-	return (status);
-}
-
-/*
- * smb_lock_range_ulckrules
- *
- *	1. Unlock should be performed at exactly matching ends.
- *	   This has been changed because overlapping ends is
- *	   allowed and there is no other precise way of locating
- *	   lock entity in node lock list.
- *
- *	2. Unlock is failed if there is no corresponding lock exists.
- *
- * Return values
- *
- *	NT_STATUS_SUCCESS		Unlock request matches lock record
- *					pointed by 'nodelock' lock structure.
- *
- *	NT_STATUS_RANGE_NOT_LOCKED	Unlock request doen't match any
- *					of lock record in node lock request or
- *					error in unlock range processing.
- */
-static uint32_t
-smb_lock_range_ulckrules(
-    struct smb_request *sr,
-    struct smb_node *node,
-    uint64_t start,
-    uint64_t length,
-    struct smb_lock **nodelock)
-{
-	smb_lock_t	*lock;
-	uint32_t	status = NT_STATUS_RANGE_NOT_LOCKED;
-
-	/* Caller must hold lock for node->n_lock_list */
-	for (lock = smb_llist_head(&node->n_lock_list);
-	    lock != NULL;
-	    lock = smb_llist_next(&node->n_lock_list, lock)) {
-
-		if ((start == lock->l_start) &&
-		    (length == lock->l_length) &&
-		    lock->l_file == sr->fid_ofile &&
-		    lock->l_session_kid == sr->session->s_kid &&
-		    lock->l_pid == sr->smb_pid &&
-		    lock->l_uid == sr->smb_uid) {
-			*nodelock = lock;
-			status = NT_STATUS_SUCCESS;
-			break;
-		}
-	}
-
-	return (status);
-}
 
 
 /*
@@ -358,13 +67,13 @@
  */
 uint32_t
 smb_unlock_range(
-    struct smb_request *sr,
-    struct smb_node *node,
-    uint64_t start,
-    uint64_t length)
+    smb_request_t	*sr,
+    smb_node_t		*node,
+    uint64_t		start,
+    uint64_t		length)
 {
-	struct smb_lock *lock = 0;
-	uint32_t status;
+	smb_lock_t	*lock = NULL;
+	uint32_t	status;
 
 	/* Apply unlocking rules */
 	smb_llist_enter(&node->n_lock_list, RW_WRITER);
@@ -374,17 +83,14 @@
 		 * If lock range is not matching in the list
 		 * return error.
 		 */
-		ASSERT(lock == 0);
+		ASSERT(lock == NULL);
 		smb_llist_exit(&node->n_lock_list);
 		return (status);
 	}
 
 	smb_llist_remove(&node->n_lock_list, lock);
-
-	smb_unlock_to_posix_unlock(sr, node, lock, B_TRUE);
-
+	smb_lock_posix_unlock(node, lock, sr->user_cr);
 	smb_llist_exit(&node->n_lock_list);
-
 	smb_lock_destroy(lock);
 
 	return (status);
@@ -393,14 +99,12 @@
 /*
  * smb_lock_range
  *
- * checks for integrity of
- * file lock operation for the given range of file data.
- * This is performed by applying lock rules with all
- * the elements of the node lock list.
+ * checks for integrity of file lock operation for the given range of file data.
+ * This is performed by applying lock rules with all the elements of the node
+ * lock list.
  *
- * The function returns with new lock added if lock
- * request is non-conflicting with existing range
- * lock for the file. Otherwise smb request is filed
+ * The function returns with new lock added if lock request is non-conflicting
+ * with existing range lock for the file. Otherwise smb request is filed
  * without returning.
  *
  * NT_STATUS_SUCCESS - Lock range performed successfully.
@@ -408,46 +112,54 @@
  */
 uint32_t
 smb_lock_range(
-    struct smb_request	*sr,
-    smb_ofile_t		*file,
+    smb_request_t	*sr,
     uint64_t		start,
     uint64_t		length,
     uint32_t		timeout,
     uint32_t		locktype)
 {
-	smb_node_t *node = file->f_node;
-	smb_lock_t *lock;
-	smb_lock_t *clock = 0;
-	uint32_t result = NT_STATUS_SUCCESS;
+	smb_ofile_t	*file = sr->fid_ofile;
+	smb_node_t	*node = file->f_node;
+	smb_lock_t	*lock;
+	smb_lock_t	*clock = NULL;
+	uint32_t	result = NT_STATUS_SUCCESS;
 
 	lock = smb_lock_create(sr, start, length, locktype, timeout);
 
 	smb_llist_enter(&node->n_lock_list, RW_WRITER);
 	for (;;) {
+		clock_t	rc;
+
 		/* Apply locking rules */
 		result = smb_lock_range_lckrules(sr, file, node, lock, &clock);
 
 		if ((result == NT_STATUS_CANCELLED) ||
 		    (result == NT_STATUS_SUCCESS) ||
 		    (result == NT_STATUS_RANGE_NOT_LOCKED)) {
-			ASSERT(clock == 0);
+			ASSERT(clock == NULL);
+			break;
+		} else if (timeout == 0) {
 			break;
-		} else {
-			ASSERT(result == NT_STATUS_LOCK_NOT_GRANTED);
-			ASSERT(clock);
-			/*
-			 * Call smb_lock_wait holding write lock for
-			 * node lock list.  smb_lock_wait will release
-			 * this lock if it blocks.
-			 */
-			ASSERT(node == clock->l_file->f_node);
-			if ((timeout == 0) ||
-			    ((result = smb_lock_wait(sr, lock, clock)) !=
-			    NT_STATUS_SUCCESS)) {
-				break;
-			}
-			clock = 0;
 		}
+
+		ASSERT(result == NT_STATUS_LOCK_NOT_GRANTED);
+		ASSERT(clock);
+		/*
+		 * Call smb_lock_wait holding write lock for
+		 * node lock list.  smb_lock_wait will release
+		 * this lock if it blocks.
+		 */
+		ASSERT(node == clock->l_file->f_node);
+
+		rc = smb_lock_wait(sr, lock, clock);
+		if (rc == 0) {
+			result = NT_STATUS_CANCELLED;
+			break;
+		}
+		if (rc == -1)
+			timeout = 0;
+
+		clock = NULL;
 	}
 
 	lock->l_blocked_by = NULL;
@@ -501,7 +213,7 @@
 		 * don't insert into the CIFS lock list unless the
 		 * posix lock worked
 		 */
-		if (smb_fsop_frlock(sr, node, lock, B_FALSE))
+		if (smb_lock_frlock(node->vp, lock, B_FALSE, sr->user_cr))
 			result = NT_STATUS_FILE_LOCK_CONFLICT;
 		else
 			smb_llist_insert_tail(&node->n_lock_list, lock);
@@ -525,11 +237,11 @@
  */
 int
 smb_lock_range_access(
-    struct smb_request *sr,
-    struct smb_node *node,
-    uint64_t start,
-    uint64_t length,
-    boolean_t will_write)
+    smb_request_t	*sr,
+    smb_node_t		*node,
+    uint64_t		start,
+    uint64_t		length,
+    boolean_t		will_write)
 {
 	smb_lock_t	*lock;
 	smb_llist_t	*llist;
@@ -539,7 +251,7 @@
 	smb_llist_enter(llist, RW_READER);
 	/* Search for any applicable lock */
 	for (lock = smb_llist_head(llist);
-	    lock != 0;
+	    lock != NULL;
 	    lock = smb_llist_next(llist, lock)) {
 
 		if (!smb_lock_range_overlap(lock, start, length))
@@ -561,81 +273,6 @@
 	return (status);
 }
 
-static smb_lock_t *
-smb_lock_create(
-    smb_request_t *sr,
-    uint64_t start,
-    uint64_t length,
-    uint32_t locktype,
-    uint32_t timeout)
-{
-	smb_lock_t *lock;
-
-	ASSERT(locktype == SMB_LOCK_TYPE_READWRITE ||
-	    locktype == SMB_LOCK_TYPE_READONLY);
-
-	lock = kmem_zalloc(sizeof (smb_lock_t), KM_SLEEP);
-	lock->l_magic = SMB_LOCK_MAGIC;
-	lock->l_sr = sr; /* Invalid after lock is active */
-	lock->l_session_kid = sr->session->s_kid;
-	lock->l_session = sr->session;
-	lock->l_file = sr->fid_ofile;
-	lock->l_uid = sr->smb_uid;
-	lock->l_pid = sr->smb_pid;
-	lock->l_type = locktype;
-	lock->l_start = start;
-	lock->l_length = length;
-	/*
-	 * Calculate the absolute end time so that we can use it
-	 * in cv_timedwait.
-	 */
-	lock->l_end_time = lbolt + MSEC_TO_TICK(timeout);
-	if (timeout == UINT_MAX) {
-		lock->l_flags |= SMB_LOCK_FLAG_INDEFINITE;
-	}
-	mutex_init(&lock->l_mutex, NULL, MUTEX_DEFAULT, NULL);
-	cv_init(&lock->l_cv, NULL, CV_DEFAULT, NULL);
-	smb_slist_constructor(&lock->l_conflict_list, sizeof (smb_lock_t),
-	    offsetof(smb_lock_t, l_conflict_lnd));
-
-	return (lock);
-}
-
-static void
-smb_lock_free(smb_lock_t *lock)
-{
-	smb_slist_destructor(&lock->l_conflict_list);
-	cv_destroy(&lock->l_cv);
-	mutex_destroy(&lock->l_mutex);
-
-	kmem_free(lock, sizeof (smb_lock_t));
-}
-
-/*
- * smb_lock_destroy
- *
- * Caller must hold node->n_lock_list
- */
-static void
-smb_lock_destroy(smb_lock_t *lock)
-{
-	/*
-	 * Caller must hold node->n_lock_list lock.
-	 */
-	mutex_enter(&lock->l_mutex);
-	cv_broadcast(&lock->l_cv);
-	mutex_exit(&lock->l_mutex);
-
-	/*
-	 * The cv_broadcast above should wake up any locks that previous
-	 * had conflicts with this lock.  Wait for the locking threads
-	 * to remove their references to this lock.
-	 */
-	smb_slist_wait_for_empty(&lock->l_conflict_list);
-
-	smb_lock_free(lock);
-}
-
 void
 smb_node_destroy_lock_by_ofile(smb_node_t *node, smb_ofile_t *file)
 {
@@ -665,6 +302,7 @@
 		nxtl = smb_llist_next(&node->n_lock_list, lock);
 		if (lock->l_file == file) {
 			smb_llist_remove(&node->n_lock_list, lock);
+			smb_lock_posix_unlock(node, lock, file->f_user->u_cred);
 			list_insert_tail(&destroy_list, lock);
 		}
 		lock = nxtl;
@@ -745,50 +383,46 @@
 }
 
 /*
- * smb_unlock_to_posix_unlock
+ * smb_lock_posix_unlock
  *
- * checks if the current unlock request is in another lock
- * and repeatedly calls smb_is_range_unlocked on a sliding basis to
- * to unlock all bits of the lock that are not in other locks
+ * checks if the current unlock request is in another lock and repeatedly calls
+ * smb_is_range_unlocked on a sliding basis to unlock all bits of the lock
+ * that are not in other locks
  *
  */
-
 void
-smb_unlock_to_posix_unlock(smb_request_t *sr, smb_node_t *node,
-    smb_lock_t *lock, boolean_t unlock)
+smb_lock_posix_unlock(smb_node_t *node, smb_lock_t *lock, cred_t *cr)
 {
-	uint64_t new_mark;
-	uint64_t unlock_start;
-	uint64_t unlock_end;
-	boolean_t unlocked;
-	smb_lock_t new_unlock;
-	smb_llist_t *llist_head;
-	int cnt = 1;
+	uint64_t	new_mark;
+	uint64_t	unlock_start;
+	uint64_t	unlock_end;
+	smb_lock_t	new_unlock;
+	smb_llist_t	*llist;
 
 	new_mark = 0;
 	unlock_start = lock->l_start;
 	unlock_end = unlock_start + lock->l_length;
-	llist_head = &node->n_lock_list;
+	llist = &node->n_lock_list;
 
-	while (cnt) {
-		if ((unlocked = smb_is_range_unlocked(unlock_start, unlock_end,
-		    llist_head, &new_mark)) == B_TRUE) {
+	for (;;) {
+		if (smb_is_range_unlocked(unlock_start, unlock_end, llist,
+		    &new_mark)) {
 			if (new_mark) {
 				new_unlock = *lock;
 				new_unlock.l_start = unlock_start;
 				new_unlock.l_length = new_mark - unlock_start;
-				(void) smb_fsop_frlock(sr, node,
-				    &new_unlock, unlock);
+				(void) smb_lock_frlock(node->vp, &new_unlock,
+				    B_TRUE, cr);
 				unlock_start = new_mark;
 			} else {
 				new_unlock = *lock;
 				new_unlock.l_start = unlock_start;
 				new_unlock.l_length = unlock_end - unlock_start;
-				(void) smb_fsop_frlock(sr, node,
-				    &new_unlock, unlock);
+				(void) smb_lock_frlock(node->vp, &new_unlock,
+				    B_TRUE, cr);
 				break;
 			}
-		} else if ((unlocked == B_FALSE) && new_mark) {
+		} else if (new_mark) {
 			unlock_start = new_mark;
 		} else {
 			break;
@@ -797,6 +431,343 @@
 }
 
 /*
+ * smb_lock_range_overlap
+ *
+ * Checks if lock range(start, length) overlaps
+ * range in lock structure.
+ *
+ * return values:
+ *	0 - Lock range doesn't overlap
+ *	1 - Lock range overlaps.
+ */
+
+#define	RANGE_NO_OVERLAP	0
+#define	RANGE_OVERLAP		1
+
+static int
+smb_lock_range_overlap(struct smb_lock *lock, uint64_t start, uint64_t length)
+{
+	/* A zero-length range doesn't overlap anything */
+	if (length == 0 || lock->l_length == 0)
+		return (RANGE_NO_OVERLAP);
+
+	if (start < lock->l_start) {
+		if (start + length > lock->l_start)
+			return (RANGE_OVERLAP);
+	} else if (start < lock->l_start + lock->l_length)
+		return (RANGE_OVERLAP);
+
+	return (RANGE_NO_OVERLAP);
+}
+
+/*
+ * smb_lock_range_lckrules
+ *
+ * Lock range rules:
+ *	1. Overlapping read locks are allowed if the
+ *	   current locks in the region are only read locks
+ *	   irrespective of pid of smb client issuing lock request.
+ *
+ *	2. Read lock in the overlapped region of write lock
+ *	   are allowed if the pervious lock is performed by the
+ *	   same pid and connection.
+ *
+ * return status:
+ *	NT_STATUS_SUCCESS - Input lock range adapts to lock rules.
+ *	NT_STATUS_LOCK_NOT_GRANTED - Input lock conflicts lock rules.
+ *	NT_STATUS_CANCELLED - Error in processing lock rules
+ */
+static uint32_t
+smb_lock_range_lckrules(
+    smb_request_t	*sr,
+    smb_ofile_t		*file,
+    smb_node_t		*node,
+    smb_lock_t		*dlock,
+    smb_lock_t		**clockp)
+{
+	smb_lock_t	*lock;
+	uint32_t	status = NT_STATUS_SUCCESS;
+
+	/* Check if file is closed */
+	if (!smb_ofile_is_open(file)) {
+		return (NT_STATUS_RANGE_NOT_LOCKED);
+	}
+
+	/* Caller must hold lock for node->n_lock_list */
+	for (lock = smb_llist_head(&node->n_lock_list);
+	    lock != NULL;
+	    lock = smb_llist_next(&node->n_lock_list, lock)) {
+
+		if (!smb_lock_range_overlap(lock, dlock->l_start,
+		    dlock->l_length))
+			continue;
+
+		/*
+		 * Check to see if lock in the overlapping record
+		 * is only read lock. Current finding is read
+		 * locks can overlapped irrespective of pids.
+		 */
+		if ((lock->l_type == SMB_LOCK_TYPE_READONLY) &&
+		    (dlock->l_type == SMB_LOCK_TYPE_READONLY)) {
+			continue;
+		}
+
+		/*
+		 * When the read lock overlaps write lock, check if
+		 * allowed.
+		 */
+		if ((dlock->l_type == SMB_LOCK_TYPE_READONLY) &&
+		    !(lock->l_type == SMB_LOCK_TYPE_READONLY)) {
+			if (lock->l_file == sr->fid_ofile &&
+			    lock->l_session_kid == sr->session->s_kid &&
+			    lock->l_pid == sr->smb_pid &&
+			    lock->l_uid == sr->smb_uid) {
+				continue;
+			}
+		}
+
+		/* Conflict in overlapping lock element */
+		*clockp = lock;
+		status = NT_STATUS_LOCK_NOT_GRANTED;
+		break;
+	}
+
+	return (status);
+}
+
+/*
+ * smb_lock_wait
+ *
+ * Wait operation for smb overlapping lock to be released.  Caller must hold
+ * write lock for node->n_lock_list so that the set of active locks can't
+ * change unexpectedly.  The lock for node->n_lock_list  will be released
+ * within this function during the sleep after the lock dependency has
+ * been recorded.
+ *
+ * return value
+ *
+ *	0	The request was canceled.
+ *	-1	The timeout was reached.
+ *	>0	Condition met.
+ */
+static clock_t
+smb_lock_wait(smb_request_t *sr, smb_lock_t *b_lock, smb_lock_t *c_lock)
+{
+	clock_t		rc;
+
+	ASSERT(sr->sr_awaiting == NULL);
+
+	mutex_enter(&sr->sr_mutex);
+
+	switch (sr->sr_state) {
+	case SMB_REQ_STATE_ACTIVE:
+		/*
+		 * Wait up till the timeout time keeping track of actual
+		 * time waited for possible retry failure.
+		 */
+		sr->sr_state = SMB_REQ_STATE_WAITING_LOCK;
+		sr->sr_awaiting = c_lock;
+		mutex_exit(&sr->sr_mutex);
+
+		mutex_enter(&c_lock->l_mutex);
+		/*
+		 * The conflict list (l_conflict_list) for a lock contains
+		 * all the locks that are blocked by and in conflict with
+		 * that lock.  Add the new lock to the conflict list for the
+		 * active lock.
+		 *
+		 * l_conflict_list is currently a fancy way of representing
+		 * the references/dependencies on a lock.  It could be
+		 * replaced with a reference count but this approach
+		 * has the advantage that MDB can display the lock
+		 * dependencies at any point in time.  In the future
+		 * we should be able to leverage the list to implement
+		 * an asynchronous locking model.
+		 *
+		 * l_blocked_by is the reverse of the conflict list.  It
+		 * points to the lock that the new lock conflicts with.
+		 * As currently implemented this value is purely for
+		 * debug purposes -- there are windows of time when
+		 * l_blocked_by may be non-NULL even though there is no
+		 * conflict list
+		 */
+		b_lock->l_blocked_by = c_lock;
+		smb_slist_insert_tail(&c_lock->l_conflict_list, b_lock);
+		smb_llist_exit(&c_lock->l_file->f_node->n_lock_list);
+
+		/*
+		 * XXX Hack.. drop s_lock to avoid blocking subsequent SMBs
+		 * that might affect the state of this lock (i.e.
+		 * smb_com_close).  We shouldn't sleep while holding
+		 * locks anyway.
+		 */
+		smb_rwx_rwexit(&sr->session->s_lock);
+
+		if (SMB_LOCK_INDEFINITE_WAIT(b_lock)) {
+			cv_wait(&c_lock->l_cv, &c_lock->l_mutex);
+		} else {
+			rc = cv_timedwait(&c_lock->l_cv,
+			    &c_lock->l_mutex, b_lock->l_end_time);
+		}
+
+		/*
+		 * XXX Hack continued from above... re-acquire s_lock
+		 * OK to hardcode RW_READER since this is just a hack and
+		 * we really should yank it out and do something else.
+		 */
+		smb_rwx_rwenter(&sr->session->s_lock, RW_READER);
+
+		mutex_exit(&c_lock->l_mutex);
+
+		smb_llist_enter(&c_lock->l_file->f_node->n_lock_list,
+		    RW_WRITER);
+		smb_slist_remove(&c_lock->l_conflict_list, b_lock);
+
+		mutex_enter(&sr->sr_mutex);
+		sr->sr_awaiting = NULL;
+		if (sr->sr_state == SMB_REQ_STATE_CANCELED) {
+			rc = 0;
+		} else {
+			sr->sr_state = SMB_REQ_STATE_ACTIVE;
+		}
+		break;
+
+	default:
+		ASSERT(sr->sr_state == SMB_REQ_STATE_CANCELED);
+		rc = 0;
+		break;
+	}
+	mutex_exit(&sr->sr_mutex);
+
+	return (rc);
+}
+
+/*
+ * smb_lock_range_ulckrules
+ *
+ *	1. Unlock should be performed at exactly matching ends.
+ *	   This has been changed because overlapping ends is
+ *	   allowed and there is no other precise way of locating
+ *	   lock entity in node lock list.
+ *
+ *	2. Unlock is failed if there is no corresponding lock exists.
+ *
+ * Return values
+ *
+ *	NT_STATUS_SUCCESS		Unlock request matches lock record
+ *					pointed by 'nodelock' lock structure.
+ *
+ *	NT_STATUS_RANGE_NOT_LOCKED	Unlock request doen't match any
+ *					of lock record in node lock request or
+ *					error in unlock range processing.
+ */
+static uint32_t
+smb_lock_range_ulckrules(
+    smb_request_t	*sr,
+    smb_node_t		*node,
+    uint64_t		start,
+    uint64_t		length,
+    smb_lock_t		**nodelock)
+{
+	smb_lock_t	*lock;
+	uint32_t	status = NT_STATUS_RANGE_NOT_LOCKED;
+
+	/* Caller must hold lock for node->n_lock_list */
+	for (lock = smb_llist_head(&node->n_lock_list);
+	    lock != NULL;
+	    lock = smb_llist_next(&node->n_lock_list, lock)) {
+
+		if ((start == lock->l_start) &&
+		    (length == lock->l_length) &&
+		    lock->l_file == sr->fid_ofile &&
+		    lock->l_session_kid == sr->session->s_kid &&
+		    lock->l_pid == sr->smb_pid &&
+		    lock->l_uid == sr->smb_uid) {
+			*nodelock = lock;
+			status = NT_STATUS_SUCCESS;
+			break;
+		}
+	}
+
+	return (status);
+}
+
+static smb_lock_t *
+smb_lock_create(
+    smb_request_t *sr,
+    uint64_t start,
+    uint64_t length,
+    uint32_t locktype,
+    uint32_t timeout)
+{
+	smb_lock_t *lock;
+
+	ASSERT(locktype == SMB_LOCK_TYPE_READWRITE ||
+	    locktype == SMB_LOCK_TYPE_READONLY);
+
+	lock = kmem_zalloc(sizeof (smb_lock_t), KM_SLEEP);
+	lock->l_magic = SMB_LOCK_MAGIC;
+	lock->l_sr = sr; /* Invalid after lock is active */
+	lock->l_session_kid = sr->session->s_kid;
+	lock->l_session = sr->session;
+	lock->l_file = sr->fid_ofile;
+	lock->l_uid = sr->smb_uid;
+	lock->l_pid = sr->smb_pid;
+	lock->l_type = locktype;
+	lock->l_start = start;
+	lock->l_length = length;
+	/*
+	 * Calculate the absolute end time so that we can use it
+	 * in cv_timedwait.
+	 */
+	lock->l_end_time = lbolt + MSEC_TO_TICK(timeout);
+	if (timeout == UINT_MAX)
+		lock->l_flags |= SMB_LOCK_FLAG_INDEFINITE;
+
+	mutex_init(&lock->l_mutex, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&lock->l_cv, NULL, CV_DEFAULT, NULL);
+	smb_slist_constructor(&lock->l_conflict_list, sizeof (smb_lock_t),
+	    offsetof(smb_lock_t, l_conflict_lnd));
+
+	return (lock);
+}
+
+static void
+smb_lock_free(smb_lock_t *lock)
+{
+	smb_slist_destructor(&lock->l_conflict_list);
+	cv_destroy(&lock->l_cv);
+	mutex_destroy(&lock->l_mutex);
+
+	kmem_free(lock, sizeof (smb_lock_t));
+}
+
+/*
+ * smb_lock_destroy
+ *
+ * Caller must hold node->n_lock_list
+ */
+static void
+smb_lock_destroy(smb_lock_t *lock)
+{
+	/*
+	 * Caller must hold node->n_lock_list lock.
+	 */
+	mutex_enter(&lock->l_mutex);
+	cv_broadcast(&lock->l_cv);
+	mutex_exit(&lock->l_mutex);
+
+	/*
+	 * The cv_broadcast above should wake up any locks that previous
+	 * had conflicts with this lock.  Wait for the locking threads
+	 * to remove their references to this lock.
+	 */
+	smb_slist_wait_for_empty(&lock->l_conflict_list);
+
+	smb_lock_free(lock);
+}
+
+/*
  * smb_is_range_unlocked
  *
  * Checks if the current unlock byte range request overlaps another lock
@@ -874,3 +845,54 @@
 	/* the range is completely unlocked */
 	return (B_TRUE);
 }
+
+/*
+ * smb_vop_frlock_callback
+ *
+ * smb wrapper function for fs_frlock
+ * this should never happen, as we are not attempting
+ * to set Mandatory Locks, cmd = F_SETLK_NBMAND
+ *
+ */
+
+static callb_cpr_t *
+/* ARGSUSED */
+smb_lock_frlock_callback(flk_cb_when_t when, void *error)
+{
+	return (0);
+}
+
+/*
+ * smb_vop_frlock
+ *
+ * smb wrapper function for fs_frlock
+ */
+static int
+smb_lock_frlock(vnode_t *vp, smb_lock_t *lock, boolean_t unlock, cred_t *cr)
+{
+	int			flag = F_REMOTELOCK;
+	flock64_t		bf;
+	flk_callback_t		flk_cb;
+
+	bzero(&bf, sizeof (bf));
+
+	flk_init_callback(&flk_cb, smb_lock_frlock_callback, NULL);
+
+	if (unlock) {
+		bf.l_type = F_UNLCK;
+	} else if (lock->l_type == SMB_LOCK_TYPE_READONLY) {
+		bf.l_type = F_RDLCK;
+		flag |= FREAD;
+	} else if (lock->l_type == SMB_LOCK_TYPE_READWRITE) {
+		bf.l_type = F_WRLCK;
+		flag |= FWRITE;
+	}
+
+	bf.l_start = lock->l_start;
+	bf.l_len = lock->l_length;
+	bf.l_pid = IGN_PID;
+	bf.l_sysid = smb_ct.cc_sysid;
+
+	return (VOP_FRLOCK(vp, F_SETLK, &bf, flag, 0, &flk_cb, cr,
+	    &smb_ct));
+}
--- a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c	Mon Apr 14 10:40:32 2008 -0700
@@ -337,8 +337,8 @@
 				return (SDRC_ERROR);
 			}
 
-			result = smb_lock_range(sr, sr->fid_ofile,
-			    offset64, length64, timeout, ltype);
+			result = smb_lock_range(sr, offset64, length64, timeout,
+			    ltype);
 			if (result != NT_STATUS_SUCCESS) {
 				smb_lock_range_error(sr, result);
 				return (SDRC_ERROR);
@@ -370,10 +370,8 @@
 				return (SDRC_ERROR);
 			}
 
-			result = smb_lock_range(sr, sr->fid_ofile,
-			    (uint64_t)offset32,
-			    (uint64_t)length32,
-			    timeout, ltype);
+			result = smb_lock_range(sr, (uint64_t)offset32,
+			    (uint64_t)length32, timeout, ltype);
 			if (result != NT_STATUS_SUCCESS) {
 				smb_lock_range_error(sr, result);
 				return (SDRC_ERROR);
--- a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c	Mon Apr 14 10:40:32 2008 -0700
@@ -361,25 +361,25 @@
 }
 
 int
-mbc_marshal_put_SID(struct mbuf_chain *mbc, nt_sid_t *pSid)
+mbc_marshal_put_SID(struct mbuf_chain *mbc, smb_sid_t *pSid)
 {
 	int	i;
 
-	if (mbc_marshal_put_char(mbc, pSid->Revision) != 0)
+	if (mbc_marshal_put_char(mbc, pSid->sid_revision) != 0)
 		return (DECODE_NO_MORE_DATA);
 
-	if (mbc_marshal_put_char(mbc, pSid->SubAuthCount) != 0)
+	if (mbc_marshal_put_char(mbc, pSid->sid_subauthcnt) != 0)
 		return (DECODE_NO_MORE_DATA);
 
 	for (i = 0; i < 6; i++) {
 		if (mbc_marshal_put_char(mbc,
-		    pSid->Authority[i]) != 0)
+		    pSid->sid_authority[i]) != 0)
 			return (DECODE_NO_MORE_DATA);
 
 	}
 
-	for (i = 0; i < pSid->SubAuthCount; i++) {
-		if (mbc_marshal_put_long(mbc, pSid->SubAuthority[i]) != 0)
+	for (i = 0; i < pSid->sid_subauthcnt; i++) {
+		if (mbc_marshal_put_long(mbc, pSid->sid_subauth[i]) != 0)
 			return (DECODE_NO_MORE_DATA);
 	}
 	return (0);
@@ -760,24 +760,24 @@
 
 
 int
-mbc_marshal_get_SID(struct mbuf_chain *mbc, nt_sid_t *pSid)
+mbc_marshal_get_SID(struct mbuf_chain *mbc, smb_sid_t *pSid)
 {
 	int	i;
 
-	if (mbc_marshal_get_char(mbc, &pSid->Revision) != 0)
+	if (mbc_marshal_get_char(mbc, &pSid->sid_revision) != 0)
 		return (DECODE_NO_MORE_DATA);
 
-	if (mbc_marshal_get_char(mbc, &pSid->SubAuthCount) != 0)
+	if (mbc_marshal_get_char(mbc, &pSid->sid_subauthcnt) != 0)
 		return (DECODE_NO_MORE_DATA);
 
 	for (i = 0; i < 6; i++) {
 		if (mbc_marshal_get_char(mbc,
-		    &pSid->Authority[i]) != 0)
+		    &pSid->sid_authority[i]) != 0)
 			return (DECODE_NO_MORE_DATA);
 	}
 
-	for (i = 0; i < pSid->SubAuthCount; i++) {
-		if (mbc_marshal_get_long(mbc, &pSid->SubAuthority[i]) != 0)
+	for (i = 0; i < pSid->sid_subauthcnt; i++) {
+		if (mbc_marshal_get_long(mbc, &pSid->sid_subauth[i]) != 0)
 			return (DECODE_NO_MORE_DATA);
 	}
 	return (0);
@@ -931,9 +931,9 @@
 			*nm = 0;
 			if (!c) fmt--;
 			if (strcmp((char *)op, "SID") == 0) {
-				nt_sid_t *sidp;
+				smb_sid_t *sidp;
 
-				sidp = va_arg(ap, nt_sid_t *);
+				sidp = va_arg(ap, smb_sid_t *);
 				(void) mbc_marshal_get_SID(mbc, sidp);
 			}
 			continue;
@@ -1334,9 +1334,9 @@
 			*nm = 0;
 			if (!c) fmt--;
 			if (strcmp((char *)op, "SID") == 0) {
-				nt_sid_t *sidp;
+				smb_sid_t *sidp;
 
-				sidp = va_arg(ap, nt_sid_t *);
+				sidp = va_arg(ap, smb_sid_t *);
 				(void) mbc_marshal_put_SID(mbc, sidp);
 			}
 			continue;
--- a/usr/src/uts/common/fs/smbsrv/smb_node.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_node.c	Mon Apr 14 10:40:32 2008 -0700
@@ -644,12 +644,10 @@
 /*
  * smb_node_get_size
  */
-uint64_t
-smb_node_get_size(
-    smb_node_t		*node,
-    smb_attr_t		*attr)
+u_offset_t
+smb_node_get_size(smb_node_t *node, smb_attr_t *attr)
 {
-	uint64_t	size;
+	u_offset_t size;
 
 	if (attr->sa_vattr.va_type == VDIR)
 		return (0);
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c	Mon Apr 14 10:40:32 2008 -0700
@@ -241,15 +241,16 @@
 		    DirFlag);
 	} else {
 		/* Named PIPE */
+		bzero(&new_attr, sizeof (smb_attr_t));
 		(void) smb_encode_mbc(&xa->rep_param_mb, "b.wllTTTTlqqwwb",
 		    0,
 		    sr->smb_fid,
 		    op->action_taken,
 		    0,	/* EaErrorOffset */
-		    0LL,
-		    0LL,
-		    0LL,
-		    0LL,
+		    &new_attr.sa_crtime,
+		    &new_attr.sa_vattr.va_atime,
+		    &new_attr.sa_vattr.va_mtime,
+		    &new_attr.sa_vattr.va_ctime,
 		    op->dattr,
 		    0x1000LL,
 		    0LL,
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c	Mon Apr 14 10:40:32 2008 -0700
@@ -32,12 +32,12 @@
 #include <smbsrv/cifs.h>
 
 static void smb_encode_sd(struct smb_xa *, smb_sd_t *, uint32_t);
-static void smb_encode_sid(struct smb_xa *, nt_sid_t *);
+static void smb_encode_sid(struct smb_xa *, smb_sid_t *);
 static void smb_encode_sacl(struct smb_xa *, smb_acl_t *);
 static void smb_encode_dacl(struct smb_xa *, smb_acl_t *);
 
 uint32_t smb_decode_sd(struct smb_xa *, smb_sd_t *);
-static nt_sid_t *smb_decode_sid(struct smb_xa *, uint32_t);
+static smb_sid_t *smb_decode_sid(struct smb_xa *, uint32_t);
 static smb_acl_t *smb_decode_acl(struct smb_xa *, uint32_t);
 
 /*
@@ -240,7 +240,7 @@
 	if (secinfo & SMB_OWNER_SECINFO) {
 		ASSERT(sd->sd_owner);
 		(void) smb_encode_mbc(&xa->rep_data_mb, "l", offset);
-		offset += nt_sid_length(sd->sd_owner);
+		offset += smb_sid_len(sd->sd_owner);
 	} else {
 		(void) smb_encode_mbc(&xa->rep_data_mb, "l", 0);
 	}
@@ -249,7 +249,7 @@
 	if (secinfo & SMB_GROUP_SECINFO) {
 		ASSERT(sd->sd_group);
 		(void) smb_encode_mbc(&xa->rep_data_mb, "l", offset);
-		offset += nt_sid_length(sd->sd_group);
+		offset += smb_sid_len(sd->sd_group);
 	} else {
 		(void) smb_encode_mbc(&xa->rep_data_mb, "l", 0);
 	}
@@ -287,21 +287,21 @@
  * Encodes given SID in the reply buffer.
  */
 static void
-smb_encode_sid(struct smb_xa *xa, nt_sid_t *sid)
+smb_encode_sid(struct smb_xa *xa, smb_sid_t *sid)
 {
 	int i;
 
 	(void) smb_encode_mbc(&xa->rep_data_mb, "bb",
-	    sid->Revision, sid->SubAuthCount);
+	    sid->sid_revision, sid->sid_subauthcnt);
 
 	for (i = 0; i < NT_SID_AUTH_MAX; i++) {
 		(void) smb_encode_mbc(&xa->rep_data_mb, "b",
-		    sid->Authority[i]);
+		    sid->sid_authority[i]);
 	}
 
-	for (i = 0; i < sid->SubAuthCount; i++) {
+	for (i = 0; i < sid->sid_subauthcnt; i++) {
 		(void) smb_encode_mbc(&xa->rep_data_mb, "l",
-		    sid->SubAuthority[i]);
+		    sid->sid_subauth[i]);
 	}
 }
 
@@ -444,22 +444,22 @@
  *
  * Allocates memory and decodes the SID in the request buffer
  * Upon successful return, caller must free the allocated memory
- * by calling MEM_FREE()
+ * by calling smb_sid_free()
  */
-static nt_sid_t *
+static smb_sid_t *
 smb_decode_sid(struct smb_xa *xa, uint32_t offset)
 {
 	uint8_t revision;
 	uint8_t subauth_cnt;
 	struct mbuf_chain sidbuf;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	int sidlen;
 	int bytes_left;
 	int i;
 
 	offset += xa->req_data_mb.chain_offset;
 	bytes_left = xa->req_data_mb.max_bytes - offset;
-	if (bytes_left < sizeof (nt_sid_t))
+	if (bytes_left < sizeof (smb_sid_t))
 		return (NULL);
 
 	(void) MBC_SHADOW_CHAIN(&sidbuf, &xa->req_data_mb, offset, bytes_left);
@@ -467,27 +467,27 @@
 	if (smb_decode_mbc(&sidbuf, "bb", &revision, &subauth_cnt))
 		return (NULL);
 
-	sidlen = sizeof (nt_sid_t) - sizeof (uint32_t) +
+	sidlen = sizeof (smb_sid_t) - sizeof (uint32_t) +
 	    (subauth_cnt * sizeof (uint32_t));
-	sid = MEM_MALLOC("smbsrv", sidlen);
+	sid = kmem_alloc(sidlen, KM_SLEEP);
 
-	sid->Revision = revision;
-	sid->SubAuthCount = subauth_cnt;
+	sid->sid_revision = revision;
+	sid->sid_subauthcnt = subauth_cnt;
 
 	for (i = 0; i < NT_SID_AUTH_MAX; i++) {
-		if (smb_decode_mbc(&sidbuf, "b", &sid->Authority[i]))
+		if (smb_decode_mbc(&sidbuf, "b", &sid->sid_authority[i]))
 			goto decode_err;
 	}
 
-	for (i = 0; i < sid->SubAuthCount; i++) {
-		if (smb_decode_mbc(&sidbuf, "l", &sid->SubAuthority[i]))
+	for (i = 0; i < sid->sid_subauthcnt; i++) {
+		if (smb_decode_mbc(&sidbuf, "l", &sid->sid_subauth[i]))
 			goto decode_err;
 	}
 
 	return (sid);
 
 decode_err:
-	MEM_FREE("smbsrv", sid);
+	kmem_free(sid, sidlen);
 	return (NULL);
 }
 
@@ -538,7 +538,7 @@
 		ace->se_sid = smb_decode_sid(xa, sid_offs);
 		if (ace->se_sid == NULL)
 			goto decode_error;
-		sidlen = nt_sid_length(ace->se_sid);
+		sidlen = smb_sid_len(ace->se_sid);
 		aclbuf.chain_offset += sidlen;
 		sid_offs += sidlen;
 	}
--- a/usr/src/uts/common/fs/smbsrv/smb_ofile.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_ofile.c	Mon Apr 14 10:40:32 2008 -0700
@@ -306,6 +306,7 @@
 			 * See comments in smb_open_subr().
 			 */
 			smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid);
+			smb_node_destroy_lock_by_ofile(of->f_node, of);
 
 			if (of->f_node->vp->v_type == VREG)
 				(void) smb_fsop_close(of);
@@ -316,7 +317,6 @@
 			 */
 			if (of->f_node->flags & NODE_FLAGS_NOTIFY_CHANGE)
 				smb_process_file_notify_change_queue(of);
-			smb_node_destroy_lock_by_ofile(of->f_node, of);
 		}
 		atomic_dec_32(&of->f_tree->t_server->sv_open_files);
 
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information.c	Mon Apr 14 10:40:32 2008 -0700
@@ -91,21 +91,20 @@
 smb_sdrc_t
 smb_com_query_information(smb_request_t *sr)
 {
-	char			*path = sr->arg.dirop.fqi.path;
-	char			*name = sr->arg.dirop.fqi.last_comp;
-	int			rc;
-	unsigned short		dattr;
-	uint32_t		write_time, file_size;
-	struct smb_node		*dir_node;
-	struct smb_node		*node;
-	smb_attr_t		attr;
-	timestruc_t		*mtime;
+	char		*path = sr->arg.dirop.fqi.path;
+	char		*name = sr->arg.dirop.fqi.last_comp;
+	int		rc;
+	uint16_t	dattr;
+	uint32_t	write_time;
+	u_offset_t	datasz;
+	smb_node_t	*dir_node;
+	smb_node_t	*node;
+	smb_attr_t	attr;
+	timestruc_t	*mtime;
 
 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
-		dattr = SMB_FA_NORMAL;
-		write_time = file_size = 0;
 		rc = smbsr_encode_result(sr, 10, 0, "bwll10.w",
-		    10, dattr, write_time, file_size, 0);
+		    10, SMB_FA_NORMAL, 0, 0, 0);
 		return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 	}
 
@@ -128,16 +127,14 @@
 	dattr = smb_node_get_dosattr(node);
 	mtime = smb_node_get_mtime(node);
 	write_time = smb_gmt2local(sr, mtime->tv_sec);
-	file_size = (uint32_t)smb_node_get_size(node, &node->attr);
+	datasz = smb_node_get_size(node, &node->attr);
+	if (datasz > UINT_MAX)
+		datasz = UINT_MAX;
 
 	smb_node_release(node);
 
 	rc = smbsr_encode_result(sr, 10, 0, "bwll10.w",
-	    10,			/* wct */
-	    dattr,
-	    write_time,		/* Last write time */
-	    file_size,		/* FileSize */
-	    0);			/* bcc */
+	    10, dattr, write_time, (uint32_t)datasz, 0);
 
 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information2.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information2.c	Mon Apr 14 10:40:32 2008 -0700
@@ -84,8 +84,9 @@
 {
 	smb_node_t *node;
 	smb_attr_t *attr;
-	uint32_t	dsize, dasize;
-	unsigned short	dattr;
+	u_offset_t size64;
+	uint32_t datasz, allocsz;
+	uint16_t dattr;
 	int rc;
 
 
@@ -104,8 +105,11 @@
 	attr = &node->attr;
 
 	dattr = smb_node_get_dosattr(node);
-	dasize = attr->sa_vattr.va_blksize * attr->sa_vattr.va_nblocks;
-	dsize = (dattr & SMB_FA_DIRECTORY) ? 0 : attr->sa_vattr.va_size;
+	size64 = smb_node_get_size(node, attr);
+	datasz = (size64 > UINT_MAX) ? UINT_MAX : (uint32_t)size64;
+
+	size64 = attr->sa_vattr.va_nblocks * DEV_BSIZE;
+	allocsz = (size64 > UINT_MAX) ? UINT_MAX : (uint32_t)size64;
 
 	rc = smbsr_encode_result(sr, 11, 0, "byyyllww",
 	    11,						/* wct */
@@ -114,8 +118,8 @@
 	    smb_gmt2local(sr, attr->sa_vattr.va_atime.tv_sec),
 	    /* LastWriteTime */
 	    smb_gmt2local(sr, attr->sa_vattr.va_mtime.tv_sec),
-	    dsize,
-	    dasize,
+	    datasz,
+	    allocsz,
 	    dattr,					/* FileAttributes */
 	    0);						/* bcc */
 
--- a/usr/src/uts/common/fs/smbsrv/smb_read.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_read.c	Mon Apr 14 10:40:32 2008 -0700
@@ -175,8 +175,8 @@
 		return (SDRC_ERROR);
 	}
 
-	status = smb_lock_range(sr, sr->fid_ofile, param->rw_offset,
-	    (uint64_t)param->rw_count, UINT_MAX, SMB_LOCK_TYPE_READWRITE);
+	status = smb_lock_range(sr, param->rw_offset, (uint64_t)param->rw_count,
+	    UINT_MAX, SMB_LOCK_TYPE_READWRITE);
 	if (status != NT_STATUS_SUCCESS) {
 		smb_lock_range_error(sr, status);
 		return (SDRC_ERROR);
--- a/usr/src/uts/common/fs/smbsrv/smb_sd.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_sd.c	Mon Apr 14 10:40:32 2008 -0700
@@ -57,12 +57,8 @@
 	ASSERT(sd);
 	ASSERT((sd->sd_control & SE_SELF_RELATIVE) == 0);
 
-	if (sd->sd_owner)
-		MEM_FREE("libnt", sd->sd_owner);
-
-	if (sd->sd_group)
-		MEM_FREE("libnt", sd->sd_group);
-
+	smb_sid_free(sd->sd_owner);
+	smb_sid_free(sd->sd_group);
 	smb_acl_free(sd->sd_dacl);
 	smb_acl_free(sd->sd_sacl);
 
@@ -75,10 +71,10 @@
 	uint32_t length = SMB_SD_HDRSIZE;
 
 	if (secinfo & SMB_OWNER_SECINFO)
-		length += nt_sid_length(sd->sd_owner);
+		length += smb_sid_len(sd->sd_owner);
 
 	if (secinfo & SMB_GROUP_SECINFO)
-		length += nt_sid_length(sd->sd_group);
+		length += smb_sid_len(sd->sd_group);
 
 	if (secinfo & SMB_DACL_SECINFO)
 		length += smb_acl_len(sd->sd_dacl);
@@ -202,7 +198,7 @@
 uint32_t
 smb_sd_tofs(smb_sd_t *sd, smb_fssd_t *fs_sd)
 {
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	uint32_t status = NT_STATUS_SUCCESS;
 	uint16_t sd_control;
 	idmap_stat idm_stat;
@@ -228,9 +224,8 @@
 	/* Owner */
 	if (fs_sd->sd_secinfo & SMB_OWNER_SECINFO) {
 		sid = sd->sd_owner;
-		if (nt_sid_is_valid(sid) == 0) {
+		if (!smb_sid_isvalid(sid))
 			return (NT_STATUS_INVALID_SID);
-		}
 
 		idtype = SMB_IDMAP_UNKNOWN;
 		idm_stat = smb_idmap_getid(sid, &fs_sd->sd_uid, &idtype);
@@ -242,9 +237,8 @@
 	/* Group */
 	if (fs_sd->sd_secinfo & SMB_GROUP_SECINFO) {
 		sid = sd->sd_group;
-		if (nt_sid_is_valid(sid) == 0) {
+		if (!smb_sid_isvalid(sid))
 			return (NT_STATUS_INVALID_SID);
-		}
 
 		idtype = SMB_IDMAP_UNKNOWN;
 		idm_stat = smb_idmap_getid(sid, &fs_sd->sd_gid, &idtype);
@@ -295,7 +289,7 @@
 {
 	uint32_t status = NT_STATUS_SUCCESS;
 	smb_acl_t *acl = NULL;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	idmap_stat idm_stat;
 
 	ASSERT(fs_sd);
--- a/usr/src/uts/common/fs/smbsrv/smb_search.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_search.c	Mon Apr 14 10:40:32 2008 -0700
@@ -233,10 +233,11 @@
 
 		(void) smb_encode_mbc(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
 
-		pc = MEM_ZALLOC("smb", sizeof (*pc));
+		pc = kmem_zalloc(sizeof (smb_odir_context_t), KM_SLEEP);
 		pc->dc_cookie = cookie;
-		node = (struct smb_node *)0;
+		node = NULL;
 		rc = 0;
+
 		while (count < maxcount) {
 			if ((rc = smb_rdir_next(sr, &node, pc)) != 0)
 				break;
@@ -244,7 +245,7 @@
 			    (strcmp(pc->dc_name, "..") == 0)) {
 				if (node) {
 					smb_node_release(node);
-					node = (struct smb_node *)0;
+					node = NULL;
 				}
 				continue;
 			}
@@ -270,10 +271,11 @@
 			    (int32_t)smb_node_get_size(node, &pc->dc_attr),
 			    name);
 			smb_node_release(node);
-			node = (struct smb_node *)0;
+			node = NULL;
 			count++;
 		}
-		MEM_FREE("smb", pc);
+
+		kmem_free(pc, sizeof (smb_odir_context_t));
 
 		if ((rc != 0) && (rc != ENOENT)) {
 			/* returned error by smb_rdir_next() */
--- a/usr/src/uts/common/fs/smbsrv/smb_server.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_server.c	Mon Apr 14 10:40:32 2008 -0700
@@ -224,6 +224,7 @@
 #include <smbsrv/smb_fsops.h>
 #include <smbsrv/lmshare.h>
 #include <smbsrv/smb_door_svc.h>
+#include <smbsrv/smb_kstat.h>
 
 extern void smb_dispatch_kstat_init(void);
 extern void smb_dispatch_kstat_fini(void);
@@ -367,7 +368,7 @@
 	    "smb_timers", smb_server_timers, sv,
 	    NULL, NULL);
 
-	sv->sv_proc = curproc;
+	sv->sv_pid = curproc->p_pid;
 
 	smb_winpipe_init();
 	(void) smb_server_kstat_init(sv);
@@ -1080,11 +1081,12 @@
 static int
 smb_server_kstat_init(smb_server_t *sv)
 {
-	(void) snprintf(sv->sv_ksp_name, sizeof (sv->sv_ksp_name),
-	    "smb_server%d", sv->sv_zid);
+	(void) snprintf(sv->sv_ksp_name, sizeof (sv->sv_ksp_name), "%s%d",
+	    SMBSRV_KSTAT_NAME, sv->sv_zid);
 
-	sv->sv_ksp = kstat_create("smbsrv", sv->sv_zid, sv->sv_ksp_name, "net",
-	    KSTAT_TYPE_NAMED, sizeof (sv->sv_ks_data) / sizeof (kstat_named_t),
+	sv->sv_ksp = kstat_create(SMBSRV_KSTAT_MODULE, 0, sv->sv_ksp_name,
+	    SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
+	    sizeof (sv->sv_ks_data) / sizeof (kstat_named_t),
 	    KSTAT_FLAG_VIRTUAL);
 
 	if (sv->sv_ksp) {
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c	Mon Apr 14 10:40:32 2008 -0700
@@ -945,8 +945,10 @@
 	char buf83[26];
 	smb_msgbuf_t mb;
 	uint32_t dattr = 0;
-	uint32_t size32 = 0;
-	uint64_t size64 = 0;
+	uint32_t dsize32 = 0;
+	uint32_t asize32 = 0;
+	u_offset_t datasz = 0;
+	u_offset_t allocsz = 0;
 	smb_node_t *lnk_snode;
 	smb_attr_t lnkattr;
 	int rc;
@@ -992,8 +994,14 @@
 	}
 
 	if (infolev != SMB_FIND_FILE_NAMES_INFO) {
-		size64 = smb_node_get_size(ient->snode, &ient->attr);
-		size32 = (size64 > 0xFFFFFFFF) ? 0xFFFFFFFF : (uint32_t)size64;
+		/* data size */
+		datasz = smb_node_get_size(ient->snode, &ient->attr);
+		dsize32 = (datasz > UINT_MAX) ? UINT_MAX : (uint32_t)datasz;
+
+		/* allocation size */
+		allocsz = ient->attr.sa_vattr.va_nblocks * DEV_BSIZE;
+		asize32 = (allocsz > UINT_MAX) ? UINT_MAX : (uint32_t)allocsz;
+
 		dattr = smb_mode_to_dos_attributes(&ient->attr);
 	}
 
@@ -1008,8 +1016,8 @@
 		    ient->attr.sa_vattr.va_mtime.tv_sec,
 		    ient->attr.sa_vattr.va_atime.tv_sec,
 		    ient->attr.sa_vattr.va_mtime.tv_sec,
-		    size32,
-		    size32,
+		    dsize32,
+		    asize32,
 		    dattr,
 		    uni_namelen,
 		    ient->name);
@@ -1025,8 +1033,8 @@
 		    ient->attr.sa_vattr.va_mtime.tv_sec,
 		    ient->attr.sa_vattr.va_atime.tv_sec,
 		    ient->attr.sa_vattr.va_mtime.tv_sec,
-		    size32,
-		    size32,
+		    dsize32,
+		    asize32,
 		    dattr,
 		    0L,		/* EA Size */
 		    uni_namelen,
@@ -1042,8 +1050,8 @@
 		    &ient->attr.sa_vattr.va_atime,
 		    &ient->attr.sa_vattr.va_mtime,
 		    &ient->attr.sa_vattr.va_ctime,
-		    size64,
-		    size64,
+		    (uint64_t)datasz,
+		    (uint64_t)allocsz,
 		    dattr,
 		    uni_namelen,
 		    ient->name);
@@ -1068,8 +1076,8 @@
 		    &ient->attr.sa_vattr.va_atime,
 		    &ient->attr.sa_vattr.va_mtime,
 		    &ient->attr.sa_vattr.va_ctime,
-		    size64,
-		    size64,
+		    (uint64_t)datasz,
+		    (uint64_t)allocsz,
 		    dattr,
 		    uni_namelen,
 		    0L,
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c	Mon Apr 14 10:40:32 2008 -0700
@@ -78,7 +78,7 @@
 {
 	static smb_attr_t pipe_attr;
 	unsigned short	infolev, dattr = 0;
-	u_offset_t	dsize = 0, dused = 0;
+	u_offset_t	datasz = 0, allocsz = 0;
 	smb_attr_t	*ap = NULL;
 	char		*namep = NULL;
 	char		*filename = NULL, *alt_nm_ptr = NULL;
@@ -138,12 +138,11 @@
 		ap = &node->attr;
 		if (ap->sa_vattr.va_type == VDIR) {
 			is_dir = 1;
-			dsize = dused = 0;
+			datasz = allocsz = 0;
 		} else {
 			is_dir = 0;
-			dsize = ap->sa_vattr.va_size;
-			dused = ap->sa_vattr.va_blksize *
-			    ap->sa_vattr.va_nblocks;
+			datasz = ap->sa_vattr.va_size;
+			allocsz = ap->sa_vattr.va_nblocks * DEV_BSIZE;
 		}
 
 		dir_snode = node->dir_snode;
@@ -166,7 +165,7 @@
 		ap = &pipe_attr;
 		creation_time = (timestruc_t *)&ap->sa_vattr.va_ctime;
 		dattr = SMB_FA_NORMAL;
-		dsize = dused = 0;
+		datasz = allocsz = 0;
 
 		delete_on_close = 0;
 		is_dir = 0;
@@ -191,10 +190,10 @@
 		break;
 
 	case SMB_INFO_STANDARD:
-		if (dsize > UINT_MAX)
-			dsize = UINT_MAX;
-		if (dused > UINT_MAX)
-			dused = UINT_MAX;
+		if (datasz > UINT_MAX)
+			datasz = UINT_MAX;
+		if (allocsz > UINT_MAX)
+			allocsz = UINT_MAX;
 
 		(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
 		(void) smb_encode_mbc(&xa->rep_data_mb,
@@ -203,16 +202,16 @@
 		    smb_gmt2local(sr, creation_time->tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_atime.tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_mtime.tv_sec),
-		    (uint32_t)dsize,
-		    (uint32_t)dused,
+		    (uint32_t)datasz,
+		    (uint32_t)allocsz,
 		    dattr);
 		break;
 
 	case SMB_INFO_QUERY_EA_SIZE:
-		if (dsize > UINT_MAX)
-			dsize = UINT_MAX;
-		if (dused > UINT_MAX)
-			dused = UINT_MAX;
+		if (datasz > UINT_MAX)
+			datasz = UINT_MAX;
+		if (allocsz > UINT_MAX)
+			allocsz = UINT_MAX;
 
 		(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
 		(void) smb_encode_mbc(&xa->rep_data_mb,
@@ -221,8 +220,8 @@
 		    smb_gmt2local(sr, creation_time->tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_atime.tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_mtime.tv_sec),
-		    (uint32_t)dsize,
-		    (uint32_t)dused,
+		    (uint32_t)datasz,
+		    (uint32_t)allocsz,
 		    dattr, 0);
 		break;
 
@@ -258,8 +257,8 @@
 		 * necessary because Win2k expects the padded bytes.
 		 */
 		(void) smb_encode_mbc(&xa->rep_data_mb, "qqlbb2.",
-		    dused,
-		    dsize,
+		    (uint64_t)allocsz,
+		    (uint64_t)datasz,
 		    ap->sa_vattr.va_nlink,
 		    delete_on_close,
 		    is_dir);
@@ -319,8 +318,8 @@
 		    &ap->sa_vattr.va_mtime,
 		    &ap->sa_vattr.va_ctime,
 		    dattr,
-		    (int64_t)dused,
-		    (int64_t)dsize,
+		    (uint64_t)allocsz,
+		    (uint64_t)datasz,
 		    ap->sa_vattr.va_nlink,
 		    delete_on_close,
 		    is_dir,
@@ -377,7 +376,7 @@
 	case SMB_QUERY_FILE_COMPRESSION_INFO:
 		(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
 		(void) smb_encode_mbc(&xa->rep_data_mb, "qwbbb3.",
-		    dsize, 0, 0, 0, 0);
+		    datasz, 0, 0, 0, 0);
 		break;
 
 	default:
@@ -445,20 +444,18 @@
 	uint32_t next_offset;
 	uint32_t stream_nlen;
 	uint32_t pad;
-	u_offset_t dsize;
+	u_offset_t datasz;
 	int is_dir;
 	uint32_t cookie = 0;
 	struct fs_stream_info *stream_info;
 	struct fs_stream_info *stream_info_next;
 	int rc = 0;
 	int done = 0;
-	char *fname;
 
 	stream_info = kmem_alloc(sizeof (struct fs_stream_info), KM_SLEEP);
 	stream_info_next = kmem_alloc(sizeof (struct fs_stream_info), KM_SLEEP);
 	is_dir = (attr->sa_vattr.va_type == VDIR) ? 1 : 0;
-	dsize = attr->sa_vattr.va_size;
-	fname = MEM_MALLOC("smb", MAXPATHLEN);
+	datasz = attr->sa_vattr.va_size;
 
 	rc = smb_fsop_stream_readdir(sr, kcred, snode, &cookie, stream_info,
 	    NULL, NULL);
@@ -471,13 +468,12 @@
 			next_offset = 0;
 
 			(void) smb_encode_mbc(&xa->rep_data_mb, "%llqqu",
-			    sr, next_offset, stream_nlen, dsize, dsize,
+			    sr, next_offset, stream_nlen, datasz, datasz,
 			    stream_name);
 		}
 		/* No named streams, we're done  */
 		kmem_free(stream_info, sizeof (struct fs_stream_info));
 		kmem_free(stream_info_next, sizeof (struct fs_stream_info));
-		MEM_FREE("smb", fname);
 		return;
 	}
 
@@ -493,7 +489,7 @@
 		    smb_ascii_or_unicode_null_len(sr);
 
 		(void) smb_encode_mbc(&xa->rep_data_mb, "%llqqu", sr,
-		    next_offset, stream_nlen, dsize, dsize, stream_name);
+		    next_offset, stream_nlen, datasz, datasz, stream_name);
 	}
 
 	while (!done) {
@@ -534,7 +530,6 @@
 	}
 	kmem_free(stream_info, sizeof (struct fs_stream_info));
 	kmem_free(stream_info_next, sizeof (struct fs_stream_info));
-	MEM_FREE("smb", fname);
 }
 
 /*
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c	Mon Apr 14 10:40:32 2008 -0700
@@ -329,7 +329,7 @@
 {
 	char			*path, *alt_nm_ptr;
 	int			rc;
-	u_offset_t		dsize, dused;
+	u_offset_t		datasz, allocsz;
 	unsigned short		infolev, dattr;
 	smb_attr_t		*ap, ret_attr;
 	struct smb_node		*dir_node;
@@ -405,19 +405,19 @@
 		 * Win2K and NT reply with the size of directory
 		 * file.
 		 */
-		dsize = dused = 0;
+		datasz = allocsz = 0;
 	} else {
 		is_dir = 0;
-		dsize = ap->sa_vattr.va_size;
-		dused = ap->sa_vattr.va_blksize * ap->sa_vattr.va_nblocks;
+		datasz = ap->sa_vattr.va_size;
+		allocsz = ap->sa_vattr.va_nblocks * DEV_BSIZE;
 	}
 
 	switch (infolev) {
 	case SMB_INFO_STANDARD:
-		if (dsize > UINT_MAX)
-			dsize = UINT_MAX;
-		if (dused > UINT_MAX)
-			dused = UINT_MAX;
+		if (datasz > UINT_MAX)
+			datasz = UINT_MAX;
+		if (allocsz > UINT_MAX)
+			allocsz = UINT_MAX;
 
 		(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
 		(void) smb_encode_mbc(&xa->rep_data_mb,
@@ -426,16 +426,16 @@
 		    smb_gmt2local(sr, ap->sa_crtime.tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_atime.tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_mtime.tv_sec),
-		    (uint32_t)dsize,
-		    (uint32_t)dused,
+		    (uint32_t)datasz,
+		    (uint32_t)allocsz,
 		    dattr);
 		break;
 
 	case SMB_INFO_QUERY_EA_SIZE:
-		if (dsize > UINT_MAX)
-			dsize = UINT_MAX;
-		if (dused > UINT_MAX)
-			dused = UINT_MAX;
+		if (datasz > UINT_MAX)
+			datasz = UINT_MAX;
+		if (allocsz > UINT_MAX)
+			allocsz = UINT_MAX;
 
 		(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
 		(void) smb_encode_mbc(&xa->rep_data_mb,
@@ -444,8 +444,8 @@
 		    smb_gmt2local(sr, ap->sa_crtime.tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_atime.tv_sec),
 		    smb_gmt2local(sr, ap->sa_vattr.va_mtime.tv_sec),
-		    (uint32_t)dsize,
-		    (uint32_t)dused,
+		    (uint32_t)datasz,
+		    (uint32_t)allocsz,
 		    dattr, 0);
 		break;
 
@@ -480,8 +480,8 @@
 		 * necessary because Win2k expects the padded bytes.
 		 */
 		(void) smb_encode_mbc(&xa->rep_data_mb, "qqlbb2.",
-		    dused,
-		    dsize,
+		    (uint64_t)allocsz,
+		    (uint64_t)datasz,
 		    ap->sa_vattr.va_nlink,
 		    (node && (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) != 0),
 		    (char)(ap->sa_vattr.va_type == VDIR));
@@ -524,8 +524,8 @@
 		    &ap->sa_vattr.va_mtime,
 		    &ap->sa_vattr.va_ctime,
 		    dattr,
-		    dused,
-		    dsize,
+		    (uint64_t)allocsz,
+		    (uint64_t)datasz,
 		    ap->sa_vattr.va_nlink,
 		    0,
 		    is_dir,
@@ -567,7 +567,7 @@
 	case SMB_QUERY_FILE_COMPRESSION_INFO:
 		(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
 		(void) smb_encode_mbc(&xa->rep_data_mb,
-		    "qwbbb3.", dsize, 0, 0, 0, 0);
+		    "qwbbb3.", datasz, 0, 0, 0, 0);
 		break;
 
 	default:
--- a/usr/src/uts/common/fs/smbsrv/smb_util.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_util.c	Mon Apr 14 10:40:32 2008 -0700
@@ -1241,15 +1241,15 @@
  * simple mapping API.
  */
 idmap_stat
-smb_idmap_getid(nt_sid_t *sid, uid_t *id, int *idtype)
+smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *idtype)
 {
 	smb_idmap_t sim;
-	nt_sid_t *tmpsid;
+	char sidstr[SMB_SID_STRSZ];
 
-	tmpsid = nt_sid_dup(sid);
-	(void) nt_sid_split(tmpsid, &sim.sim_rid);
-	sim.sim_domsid = nt_sid_format(tmpsid);
-	MEM_FREE("smbsrv", tmpsid);
+	smb_sid_tostr(sid, sidstr);
+	if (smb_sid_splitstr(sidstr, &sim.sim_rid) != 0)
+		return (IDMAP_ERR_SID);
+	sim.sim_domsid = sidstr;
 	sim.sim_id = id;
 
 	switch (*idtype) {
@@ -1274,7 +1274,6 @@
 	}
 
 	*idtype = sim.sim_idtype;
-	MEM_FREE("smbsrv", sim.sim_domsid);
 
 	return (sim.sim_stat);
 }
@@ -1286,7 +1285,7 @@
  * simple mapping API.
  */
 idmap_stat
-smb_idmap_getsid(uid_t id, int idtype, nt_sid_t **sid)
+smb_idmap_getsid(uid_t id, int idtype, smb_sid_t **sid)
 {
 	smb_idmap_t sim;
 
@@ -1316,17 +1315,15 @@
 	if (sim.sim_stat != IDMAP_SUCCESS)
 		return (sim.sim_stat);
 
-	if (sim.sim_domsid == NULL) {
+	if (sim.sim_domsid == NULL)
 		return (IDMAP_ERR_NOMAPPING);
-	}
 
-	sim.sim_sid = nt_sid_strtosid(sim.sim_domsid);
-	if (sim.sim_sid == NULL) {
+	sim.sim_sid = smb_sid_fromstr(sim.sim_domsid);
+	if (sim.sim_sid == NULL)
 		return (IDMAP_ERR_INTERNAL);
-	}
 
-	*sid = nt_sid_splice(sim.sim_sid, sim.sim_rid);
-	MEM_FREE("smbsrv", sim.sim_sid);
+	*sid = smb_sid_splice(sim.sim_sid, sim.sim_rid);
+	smb_sid_free(sim.sim_sid);
 	if (*sid == NULL)
 		sim.sim_stat = IDMAP_ERR_INTERNAL;
 
@@ -1365,7 +1362,6 @@
 void
 smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
 {
-	nt_sid_t *sid;
 	char *domsid;
 	int i;
 
@@ -1380,11 +1376,8 @@
 		 * SIDs are allocated only when mapping
 		 * UID/GID to SIDs
 		 */
-		for (i = 0; i < sib->sib_nmap; i++) {
-			sid = sib->sib_maps[i].sim_sid;
-			if (sid)
-				MEM_FREE("smbsrv", sid);
-		}
+		for (i = 0; i < sib->sib_nmap; i++)
+			smb_sid_free(sib->sib_maps[i].sim_sid);
 	} else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
 		/*
 		 * SID prefixes are allocated only when mapping
@@ -1393,7 +1386,7 @@
 		for (i = 0; i < sib->sib_nmap; i++) {
 			domsid = sib->sib_maps[i].sim_domsid;
 			if (domsid)
-				MEM_FREE("smbsrv", domsid);
+				kmem_free(domsid, strlen(domsid) + 1);
 		}
 	}
 
@@ -1415,19 +1408,19 @@
  */
 idmap_stat
 smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
-    nt_sid_t *sid, int idtype)
+    smb_sid_t *sid, int idtype)
 {
-	nt_sid_t *tmpsid;
+	char strsid[SMB_SID_STRSZ];
 	idmap_stat idm_stat;
 
 	ASSERT(idmaph);
 	ASSERT(sim);
 	ASSERT(sid);
 
-	tmpsid = nt_sid_dup(sid);
-	(void) nt_sid_split(tmpsid, &sim->sim_rid);
-	sim->sim_domsid = nt_sid_format(tmpsid);
-	MEM_FREE("smbsrv", tmpsid);
+	smb_sid_tostr(sid, strsid);
+	if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
+		return (IDMAP_ERR_SID);
+	sim->sim_domsid = smb_kstrdup(strsid, strlen(strsid) + 1);
 
 	switch (idtype) {
 	case SMB_IDMAP_USER:
@@ -1507,7 +1500,7 @@
 static int
 smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
 {
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 	smb_idmap_t *sim;
 	int i;
 
@@ -1518,17 +1511,14 @@
 	sim = sib->sib_maps;
 	for (i = 0; i < sib->sib_nmap; sim++, i++) {
 		ASSERT(sim->sim_domsid);
-		if (sim->sim_domsid == NULL) {
+		if (sim->sim_domsid == NULL)
 			return (1);
-		}
 
-		sid = nt_sid_strtosid(sim->sim_domsid);
-		if (sid == NULL) {
+		if ((sid = smb_sid_fromstr(sim->sim_domsid)) == NULL)
 			return (1);
-		}
 
-		sim->sim_sid = nt_sid_splice(sid, sim->sim_rid);
-		MEM_FREE("smbsrv", sid);
+		sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
+		smb_sid_free(sid);
 	}
 
 	return (0);
@@ -1551,22 +1541,19 @@
 	int i;
 
 	idm_stat = kidmap_get_mappings(sib->sib_idmaph);
-	if (idm_stat != IDMAP_SUCCESS) {
+	if (idm_stat != IDMAP_SUCCESS)
 		return (idm_stat);
-	}
 
 	/*
 	 * Check the status for all the queued requests
 	 */
 	for (i = 0; i < sib->sib_nmap; i++) {
-		if (sib->sib_maps[i].sim_stat != IDMAP_SUCCESS) {
+		if (sib->sib_maps[i].sim_stat != IDMAP_SUCCESS)
 			return (sib->sib_maps[i].sim_stat);
-		}
 	}
 
-	if (smb_idmap_batch_binsid(sib) != 0) {
+	if (smb_idmap_batch_binsid(sib) != 0)
 		idm_stat = IDMAP_ERR_OTHER;
-	}
 
 	return (idm_stat);
 }
@@ -1808,23 +1795,19 @@
 static void
 smb_cred_set_sid(smb_id_t *id, ksid_t *ksid)
 {
-	nt_sid_t *domain_sid = NULL;
-	char *domain_sid_buf = NULL;
+	char sidstr[SMB_SID_STRSZ];
 	int rc;
 
 	ASSERT(id);
 	ASSERT(id->i_sidattr.sid);
 
 	ksid->ks_id = id->i_id;
-	domain_sid = nt_sid_dup(id->i_sidattr.sid);
-	rc = nt_sid_split(domain_sid, &ksid->ks_rid);
+	smb_sid_tostr(id->i_sidattr.sid, sidstr);
+	rc = smb_sid_splitstr(sidstr, &ksid->ks_rid);
 	ASSERT(rc == 0);
 
 	ksid->ks_attr = id->i_sidattr.attrs;
-	domain_sid_buf = nt_sid_format(domain_sid);
-	ksid->ks_domain = ksid_lookupdomain(domain_sid_buf);
-	MEM_FREE("smbsrv", domain_sid);
-	MEM_FREE("smbsrv", domain_sid_buf);
+	ksid->ks_domain = ksid_lookupdomain(sidstr);
 }
 
 /*
@@ -1951,7 +1934,7 @@
  * of the user's cred.
  */
 int
-smb_cred_is_member(cred_t *cr, nt_sid_t *sid)
+smb_cred_is_member(cred_t *cr, smb_sid_t *sid)
 {
 	ksidlist_t *ksidlist;
 	ksid_t ksid1, *ksid2;
--- a/usr/src/uts/common/fs/smbsrv/smb_vops.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c	Mon Apr 14 10:40:32 2008 -0700
@@ -117,7 +117,7 @@
 		return (ENOMEM);
 
 	smb_ct.cc_caller_id = fs_new_caller_id();
-	smb_ct.cc_pid = 0;
+	smb_ct.cc_pid = IGN_PID;
 	smb_ct.cc_flags = 0;
 
 	smb_vop_initialized = B_TRUE;
@@ -137,6 +137,7 @@
 		return;
 
 	lm_free_sysidt(smb_ct.cc_sysid);
+	smb_ct.cc_pid = IGN_PID;
 	smb_ct.cc_sysid = LM_NOSYSID;
 	smb_vop_initialized = B_FALSE;
 }
--- a/usr/src/uts/common/fs/smbsrv/smb_winpipe.c	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/fs/smbsrv/smb_winpipe.c	Mon Apr 14 10:40:32 2008 -0700
@@ -37,12 +37,11 @@
 #include <sys/stat.h>
 #include <sys/door.h>
 #include <sys/door_data.h>
-#include <smbsrv/ntsid.h>
-#include <smbsrv/ntsid.h>
+#include <sys/uio.h>
+
 #include <smbsrv/ndr.h>
 #include <smbsrv/mlrpc.h>
 #include <smbsrv/mlsvc_util.h>
-#include <sys/uio.h>
 
 
 static door_handle_t smb_winpipe_dh = NULL;
--- a/usr/src/uts/common/smbsrv/Makefile	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/Makefile	Mon Apr 14 10:40:32 2008 -0700
@@ -63,7 +63,7 @@
 	nterror.h		\
 	ntifs.h			\
 	ntlocale.h		\
-	ntsid.h			\
+	smb_sid.h		\
 	ntstatus.h		\
 	oem.h			\
 	samlib.h		\
@@ -77,6 +77,7 @@
 	smb_incl.h		\
 	smb_ioctl.h		\
 	smb_kproto.h		\
+	smb_kstat.h		\
 	smb_ktypes.h		\
 	smb_privilege.h		\
 	smb_token.h		\
--- a/usr/src/uts/common/smbsrv/lsalib.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/lsalib.h	Mon Apr 14 10:40:32 2008 -0700
@@ -39,7 +39,7 @@
 
 #include <smbsrv/ndl/lsarpc.ndl>
 #include <smbsrv/mlsvc_util.h>
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 
 
 #ifdef __cplusplus
@@ -51,7 +51,7 @@
  * lsalib.c
  */
 uint32_t lsa_lookup_name(char *, char *, uint16_t, smb_userinfo_t *);
-uint32_t lsa_lookup_sid(nt_sid_t *, smb_userinfo_t *);
+uint32_t lsa_lookup_sid(smb_sid_t *, smb_userinfo_t *);
 
 int lsa_lookup_privs(char *server,
     char *account_name,
--- a/usr/src/uts/common/smbsrv/mlsvc.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/mlsvc.h	Mon Apr 14 10:40:32 2008 -0700
@@ -37,8 +37,6 @@
 #include <sys/ksynch.h>
 
 #include <smbsrv/wintypes.h>
-#include <smbsrv/ntsid.h>
-
 #include <smbsrv/smb_winpipe.h>
 #include <smbsrv/smb_xdr.h>
 
--- a/usr/src/uts/common/smbsrv/mlsvc_util.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/mlsvc_util.h	Mon Apr 14 10:40:32 2008 -0700
@@ -36,7 +36,7 @@
 #include <smbsrv/ndr.h>
 #include <smbsrv/mlrpc.h>
 #include <smbsrv/mlsvc.h>
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 #include <smbsrv/smb_token.h>
 
 #ifndef _KERNEL
@@ -78,7 +78,7 @@
 typedef struct ms_string_desc ms_string_t;
 
 int mlsvc_string_save(ms_string_t *ms, char *str, struct mlrpc_xaction *mxa);
-nt_sid_t *mlsvc_sid_save(nt_sid_t *sid, struct mlrpc_xaction *mxa);
+smb_sid_t *mlsvc_sid_save(smb_sid_t *sid, struct mlrpc_xaction *mxa);
 
 /*
  * This is the generic, interface independent handle definition.
--- a/usr/src/uts/common/smbsrv/ntsid.h	Mon Apr 14 10:25:34 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,304 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SMBSRV_NTSID_H
-#define	_SMBSRV_NTSID_H
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*
- * NT Security Identifier (SID) interface definition.
- */
-
-/*
- * some kernel include file /usr/include/... is
- * overriding DWORD and causing conflicts
- * will investigate further - to be removed
- */
-
-#ifdef DWORD
-#undef DWORD
-#define	DWORD uint32_t
-#endif
-
-#include <smbsrv/wintypes.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Predefined global user RIDs.
- */
-#define	DOMAIN_USER_RID_ADMIN		(0x000001F4L)	/* 500 */
-#define	DOMAIN_USER_RID_GUEST		(0x000001F5L)	/* 501 */
-#define	DOMAIN_USER_RID_KRBTGT		(0x000001F6L)	/* 502 */
-
-/*
- * Predefined global group RIDs.
- */
-#define	DOMAIN_GROUP_RID_ADMINS		(0x00000200L)	/* 512 */
-#define	DOMAIN_GROUP_RID_USERS		(0x00000201L)
-#define	DOMAIN_GROUP_RID_GUESTS		(0x00000202L)
-#define	DOMAIN_GROUP_RID_COMPUTERS	(0x00000203L)
-#define	DOMAIN_GROUP_RID_CONTROLLERS	(0x00000204L)
-#define	DOMAIN_GROUP_RID_CERT_ADMINS	(0x00000205L)
-#define	DOMAIN_GROUP_RID_SCHEMA_ADMINS	(0x00000206L)
-
-
-/*
- * Predefined local alias RIDs.
- */
-#define	DOMAIN_ALIAS_RID_ADMINS		(0x00000220L)	/* 544 */
-#define	DOMAIN_ALIAS_RID_USERS		(0x00000221L)
-#define	DOMAIN_ALIAS_RID_GUESTS		(0x00000222L)
-#define	DOMAIN_ALIAS_RID_POWER_USERS	(0x00000223L)
-#define	DOMAIN_ALIAS_RID_ACCOUNT_OPS	(0x00000224L)
-#define	DOMAIN_ALIAS_RID_SYSTEM_OPS	(0x00000225L)
-#define	DOMAIN_ALIAS_RID_PRINT_OPS	(0x00000226L)
-#define	DOMAIN_ALIAS_RID_BACKUP_OPS	(0x00000227L)
-#define	DOMAIN_ALIAS_RID_REPLICATOR	(0x00000228L)
-
-
-/*
- * Universal and NT well-known SIDs
- */
-#define	NT_NULL_SIDSTR				"S-1-0-0"
-#define	NT_WORLD_SIDSTR				"S-1-1-0"
-#define	NT_LOCAL_SIDSTR				"S-1-2-0"
-#define	NT_CREATOR_OWNER_ID_SIDSTR		"S-1-3-0"
-#define	NT_CREATOR_GROUP_ID_SIDSTR		"S-1-3-1"
-#define	NT_CREATOR_OWNER_SERVER_ID_SIDSTR	"S-1-3-2"
-#define	NT_CREATOR_GROUP_SERVER_ID_SIDSTR	"S-1-3-3"
-#define	NT_NON_UNIQUE_IDS_SIDSTR		"S-1-4"
-#define	NT_AUTHORITY_SIDSTR			"S-1-5"
-#define	NT_DIALUP_SIDSTR			"S-1-5-1"
-#define	NT_NETWORK_SIDSTR			"S-1-5-2"
-#define	NT_BATCH_SIDSTR				"S-1-5-3"
-#define	NT_INTERACTIVE_SIDSTR			"S-1-5-4"
-#define	NT_SERVICE_SIDSTR			"S-1-5-6"
-#define	NT_ANONYMOUS_LOGON_SIDSTR		"S-1-5-7"
-#define	NT_PROXY_SIDSTR				"S-1-5-8"
-#define	NT_SERVER_LOGON_SIDSTR			"S-1-5-9"
-#define	NT_SELF_SIDSTR				"S-1-5-10"
-#define	NT_AUTHENTICATED_USER_SIDSTR		"S-1-5-11"
-#define	NT_RESTRICTED_CODE_SIDSTR		"S-1-5-12"
-#define	NT_LOCAL_SYSTEM_SIDSTR			"S-1-5-18"
-#define	NT_NON_UNIQUE_SIDSTR			"S-1-5-21"
-#define	NT_BUILTIN_DOMAIN_SIDSTR		"S-1-5-32"
-
-
-/*
- * SID type indicators (SID_NAME_USE).
- */
-#define	SidTypeNull			0
-#define	SidTypeUser			1
-#define	SidTypeGroup			2
-#define	SidTypeDomain			3
-#define	SidTypeAlias			4
-#define	SidTypeWellKnownGroup		5
-#define	SidTypeDeletedAccount		6
-#define	SidTypeInvalid			7
-#define	SidTypeUnknown			8
-#define	SidTypeComputer			9
-
-
-/*
- * Identifier authorities for various domains.
- */
-#define	NT_SID_NULL_AUTH		0
-#define	NT_SID_WORLD_AUTH		1
-#define	NT_SID_LOCAL_AUTH		2
-#define	NT_SID_CREATOR_AUTH		3
-#define	NT_SID_NON_UNIQUE_AUTH		4
-#define	NT_SID_NT_AUTH			5
-
-
-#define	NT_SECURITY_NULL_AUTH		{0, 0, 0, 0, 0, 0}
-#define	NT_SECURITY_WORLD_AUTH		{0, 0, 0, 0, 0, 1}
-#define	NT_SECURITY_LOCAL_AUTH		{0, 0, 0, 0, 0, 2}
-#define	NT_SECURITY_CREATOR_AUTH	{0, 0, 0, 0, 0, 3}
-#define	NT_SECURITY_NON_UNIQUE_AUTH	{0, 0, 0, 0, 0, 4}
-#define	NT_SECURITY_NT_AUTH		{0, 0, 0, 0, 0, 5}
-#define	NT_SECURITY_UNIX_AUTH		{0, 0, 0, 0, 0, 99}
-
-
-#define	SECURITY_NULL_RID			(0x00000000L)
-#define	SECURITY_WORLD_RID			(0x00000000L)
-#define	SECURITY_LOCAL_RID			(0X00000000L)
-
-#define	SECURITY_CREATOR_OWNER_RID		(0x00000000L)
-#define	SECURITY_CREATOR_GROUP_RID		(0x00000001L)
-#define	SECURITY_CREATOR_OWNER_SERVER_RID	(0x00000002L)
-#define	SECURITY_CREATOR_GROUP_SERVER_RID	(0x00000003L)
-
-#define	SECURITY_DIALUP_RID			(0x00000001L)
-#define	SECURITY_NETWORK_RID			(0x00000002L)
-#define	SECURITY_BATCH_RID			(0x00000003L)
-#define	SECURITY_INTERACTIVE_RID		(0x00000004L)
-#define	SECURITY_LOGON_IDS_RID			(0x00000005L)
-#define	SECURITY_LOGON_IDS_RID_COUNT		(3L)
-#define	SECURITY_SERVICE_RID			(0x00000006L)
-#define	SECURITY_ANONYMOUS_LOGON_RID		(0x00000007L)
-#define	SECURITY_PROXY_RID			(0x00000008L)
-#define	SECURITY_ENTERPRISE_CONTROLLERS_RID	(0x00000009L)
-#define	SECURITY_SERVER_LOGON_RID	SECURITY_ENTERPRISE_CONTROLLERS_RID
-#define	SECURITY_PRINCIPAL_SELF_RID		(0x0000000AL)
-#define	SECURITY_AUTHENTICATED_USER_RID		(0x0000000BL)
-#define	SECURITY_RESTRICTED_CODE_RID		(0x0000000CL)
-
-#define	SECURITY_LOCAL_SYSTEM_RID		(0x00000012L)
-#define	SECURITY_NT_NON_UNIQUE			(0x00000015L)
-#define	SECURITY_BUILTIN_DOMAIN_RID		(0x00000020L)
-
-
-#define	NT_SID_NON_UNIQUE_SUBAUTH 21
-
-
-/*
- * Common definition for a SID.
- */
-#define	NT_SID_REVISION		1
-#define	NT_SID_AUTH_MAX		6
-#define	NT_SID_SUBAUTH_MAX	15
-
-
-/*
- * Security Identifier (SID)
- *
- * The security identifier (SID) uniquely identifies a user, group or
- * a domain. It consists of a revision number, the identifier authority,
- * and a list of sub-authorities. The revision number is currently 1.
- * The identifier authority identifies which system issued the SID. The
- * sub-authorities of a domain SID uniquely identify a domain. A user
- * or group SID consists of a domain SID with the user or group id
- * appended. The user or group id (also known as a relative id (RID)
- * uniquely identifies a user within a domain. A user or group SID
- * uniquely identifies a user or group across all domains. The SidType
- * values identify the various types of SID.
- *
- *      1   1   1   1   1   1
- *      5   4   3   2   1   0   9   8   7   6   5   4   3   2   1   0
- *   +---------------------------------------------------------------+
- *   |      SubAuthorityCount        |Reserved1 (SBZ)|   Revision    |
- *   +---------------------------------------------------------------+
- *   |                   IdentifierAuthority[0]                      |
- *   +---------------------------------------------------------------+
- *   |                   IdentifierAuthority[1]                      |
- *   +---------------------------------------------------------------+
- *   |                   IdentifierAuthority[2]                      |
- *   +---------------------------------------------------------------+
- *   |                                                               |
- *   +- -  -  -  -  -  -  -  SubAuthority[]  -  -  -  -  -  -  -  - -+
- *   |                                                               |
- *   +---------------------------------------------------------------+
- *
- */
-/*
- * Note: NT defines the Identifier Authority as a separate
- * structure (SID_IDENTIFIER_AUTHORITY) containing a literal
- * definition of a 6 byte vector but the effect is the same
- * as defining it as a member value.
- */
-typedef struct nt_sid {
-	BYTE Revision;
-	BYTE SubAuthCount;
-	BYTE Authority[NT_SID_AUTH_MAX];
-	DWORD SubAuthority[ANY_SIZE_ARRAY];
-} nt_sid_t;
-
-/*
- * The structure for entries in a static table of well known
- * SIDs. The table definition is in os/libnt/ntbuitin.c
- * The domain_ix field is an index into a predefined domain
- * list in os/libnt/ntbuitin.c
- */
-typedef struct well_known_account {
-	WORD sid_name_use;
-	WORD domain_ix;			/* index to a predefine domain list */
-	char *sid;
-	char *name;
-	WORD flags;
-	char *desc;
-	nt_sid_t *binsid;
-} well_known_account_t;
-
-/*
- * flags for local group table entry
- *
- * LGF_HIDDEN		this entry won't be represented to users
- *					via builtin group management interface
- */
-#define	LGF_HIDDEN			0x1
-
-
-/*
- * The maximum size of the SID format buffer.
- */
-#define	NT_SID_FMTBUF_SIZE		256
-
-
-int nt_sid_is_valid(nt_sid_t *sid);
-int nt_sid_length(nt_sid_t *sid);
-nt_sid_t *nt_sid_dup(nt_sid_t *sid);
-nt_sid_t *nt_sid_splice(nt_sid_t *domain_sid, DWORD rid);
-int nt_sid_get_rid(nt_sid_t *sid, DWORD *rid);
-int nt_sid_split(nt_sid_t *sid, DWORD *rid);
-nt_sid_t *nt_sid_gen_null_sid(void);
-int nt_sid_domain_equal(nt_sid_t *domain_sid, nt_sid_t *sid);
-int nt_sid_is_equal(nt_sid_t *sid1, nt_sid_t *sid2);
-int nt_sid_is_local(nt_sid_t *sid);
-int nt_sid_is_builtin(nt_sid_t *sid);
-int nt_sid_is_domain_equal(nt_sid_t *sid1, nt_sid_t *sid2);
-int nt_sid_is_indomain(nt_sid_t *domain_sid, nt_sid_t *sid);
-void nt_sid_logf(nt_sid_t *sid);
-char *nt_sid_format(nt_sid_t *sid);
-void nt_sid_format2(nt_sid_t *sid, char *fmtbuf);
-nt_sid_t *nt_sid_strtosid(char *sidstr);
-char *nt_sid_name_use(unsigned int snu_id);
-int nt_sid_copy(nt_sid_t *dessid, nt_sid_t *srcsid, unsigned buflen);
-
-
-/*
- * SID/name translation service for NT BUILTIN SIDs.
- */
-int nt_builtin_init(void);
-void nt_builtin_fini(void);
-well_known_account_t *nt_builtin_lookup(char *name);
-char *nt_builtin_lookup_sid(nt_sid_t *sid, WORD *sid_name_use);
-nt_sid_t *nt_builtin_lookup_name(char *name, WORD *sid_name_use);
-char *nt_builtin_lookup_domain(char *name);
-int nt_builtin_is_wellknown(char *name);
-well_known_account_t *nt_builtin_findfirst(DWORD *iterator);
-well_known_account_t *nt_builtin_findnext(DWORD *iterator);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* _SMBSRV_NTSID_H */
--- a/usr/src/uts/common/smbsrv/smb_fsops.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/smb_fsops.h	Mon Apr 14 10:40:32 2008 -0700
@@ -34,8 +34,8 @@
  */
 #include <smbsrv/smb_i18n.h>
 #include <smbsrv/smbinfo.h>
+#include <smbsrv/smb_ktypes.h>
 #include <smbsrv/smb_vops.h>
-#include <smbsrv/smb_ktypes.h>
 #include <sys/callb.h>
 #include <sys/flock.h>
 
@@ -123,7 +123,6 @@
 
 uint32_t smb_fsop_shrlock(cred_t *, smb_node_t *, uint32_t, uint32_t, uint32_t);
 void smb_fsop_unshrlock(cred_t *cr, smb_node_t *node, uint32_t uniq_fid);
-int smb_fsop_frlock(smb_request_t *, smb_node_t *, smb_lock_t *, boolean_t);
 
 /*
  * Lookup-related flags
--- a/usr/src/uts/common/smbsrv/smb_idmap.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/smb_idmap.h	Mon Apr 14 10:40:32 2008 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -34,7 +34,7 @@
 #include <idmap.h>
 #endif
 
-#include <smbsrv/ntsid.h>
+#include <smbsrv/smb_sid.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -69,7 +69,7 @@
 	uid_t		*sim_id;
 	char		*sim_domsid;
 	uint32_t	sim_rid;
-	nt_sid_t	*sim_sid;
+	smb_sid_t	*sim_sid;
 	idmap_stat	sim_stat;
 } smb_idmap_t;
 
@@ -81,14 +81,14 @@
 	idmap_get_handle_t 	*sib_idmaph;
 } smb_idmap_batch_t;
 
-idmap_stat smb_idmap_getsid(uid_t, int, nt_sid_t **);
-idmap_stat smb_idmap_getid(nt_sid_t *, uid_t *, int *);
+idmap_stat smb_idmap_getsid(uid_t, int, smb_sid_t **);
+idmap_stat smb_idmap_getid(smb_sid_t *, uid_t *, int *);
 
 void smb_idmap_batch_destroy(smb_idmap_batch_t *);
 idmap_stat smb_idmap_batch_create(smb_idmap_batch_t *, uint16_t, int);
 idmap_stat smb_idmap_batch_getmappings(smb_idmap_batch_t *);
 idmap_stat smb_idmap_batch_getid(idmap_get_handle_t *, smb_idmap_t *,
-    nt_sid_t *, int);
+    smb_sid_t *, int);
 idmap_stat smb_idmap_batch_getsid(idmap_get_handle_t *, smb_idmap_t *,
     uid_t, int);
 
--- a/usr/src/uts/common/smbsrv/smb_kproto.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/smb_kproto.h	Mon Apr 14 10:40:32 2008 -0700
@@ -201,8 +201,8 @@
 
 uint32_t smb_unlock_range(struct smb_request *, struct smb_node *,
     uint64_t, uint64_t);
-uint32_t smb_lock_range(struct smb_request *, struct smb_ofile *,
-    uint64_t, uint64_t, uint32_t, uint32_t);
+uint32_t smb_lock_range(smb_request_t *, uint64_t, uint64_t, uint32_t,
+    uint32_t locktype);
 void smb_lock_range_error(smb_request_t *, uint32_t);
 
 DWORD smb_range_check(smb_request_t *, cred_t *, smb_node_t *,
@@ -369,7 +369,7 @@
 DWORD smb_node_rename_check(smb_node_t *);
 DWORD smb_node_delete_check(smb_node_t *);
 
-uint64_t smb_node_get_size(smb_node_t *node, smb_attr_t *attr);
+u_offset_t smb_node_get_size(smb_node_t *, smb_attr_t *);
 void smb_node_set_time(struct smb_node *node, timestruc_t *crtime,
     timestruc_t *mtime, timestruc_t *atime,
     timestruc_t *ctime, unsigned int what);
@@ -565,7 +565,7 @@
  */
 cred_t *smb_cred_create(smb_token_t *, uint32_t *);
 void smb_cred_rele(cred_t *cr);
-int smb_cred_is_member(cred_t *cr, nt_sid_t *sid);
+int smb_cred_is_member(cred_t *cr, smb_sid_t *sid);
 
 smb_xa_t *smb_xa_create(smb_session_t *session, smb_request_t *sr,
     uint32_t total_parameter_count, uint32_t total_data_count,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/smbsrv/smb_kstat.h	Mon Apr 14 10:40:32 2008 -0700
@@ -0,0 +1,47 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Kstat definitions for the SMB server module.
+ */
+#ifndef _SMBSRV_SMB_KSTAT_H
+#define	_SMBSRV_SMB_KSTAT_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	SMBSRV_KSTAT_MODULE	"smbsrv"
+#define	SMBSRV_KSTAT_CLASS	"net"
+#define	SMBSRV_KSTAT_NAME	"smbsrv"
+#define	SMBSRV_KSTAT_NAME_CMDS	"smbsrv_commands"
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SMBSRV_SMB_KSTAT_H */
--- a/usr/src/uts/common/smbsrv/smb_ktypes.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/smb_ktypes.h	Mon Apr 14 10:40:32 2008 -0700
@@ -52,6 +52,7 @@
 #include <smbsrv/lmshare.h>
 #include <smbsrv/smbinfo.h>
 #include <smbsrv/mbuf.h>
+#include <smbsrv/smb_sid.h>
 
 #include <smbsrv/smb_vops.h>
 #include <smbsrv/smb_fsd.h>
@@ -59,7 +60,7 @@
 
 struct smb_request;
 struct smb_server;
-typedef struct smb_sd smb_sd_t;
+struct smb_sd;
 
 int smb_noop(void *, size_t, int);
 
@@ -640,7 +641,8 @@
 	SMB_SESSION_STATE_NEGOTIATED,
 	SMB_SESSION_STATE_OPLOCK_BREAKING,
 	SMB_SESSION_STATE_WRITE_RAW_ACTIVE,
-	SMB_SESSION_STATE_TERMINATED
+	SMB_SESSION_STATE_TERMINATED,
+	SMB_SESSION_STATE_SENTINEL
 } smb_session_state_t;
 
 typedef struct smb_session {
@@ -715,7 +717,8 @@
 typedef enum {
 	SMB_USER_STATE_LOGGED_IN = 0,
 	SMB_USER_STATE_LOGGING_OFF,
-	SMB_USER_STATE_LOGGED_OFF
+	SMB_USER_STATE_LOGGED_OFF,
+	SMB_USER_STATE_SENTINEL
 } smb_user_state_t;
 
 typedef struct smb_user {
@@ -749,7 +752,8 @@
 typedef enum {
 	SMB_TREE_STATE_CONNECTED = 0,
 	SMB_TREE_STATE_DISCONNECTING,
-	SMB_TREE_STATE_DISCONNECTED
+	SMB_TREE_STATE_DISCONNECTED,
+	SMB_TREE_STATE_SENTINEL
 } smb_tree_state_t;
 
 typedef struct smb_tree {
@@ -860,7 +864,8 @@
 typedef enum {
 	SMB_OFILE_STATE_OPEN = 0,
 	SMB_OFILE_STATE_CLOSING,
-	SMB_OFILE_STATE_CLOSED
+	SMB_OFILE_STATE_CLOSED,
+	SMB_OFILE_STATE_SENTINEL
 } smb_ofile_state_t;
 
 typedef struct smb_ofile {
@@ -890,6 +895,7 @@
 	uint16_t		f_ftype;
 	uint64_t		f_llf_pos;
 	cred_t			*f_cr;
+	pid_t			f_pid;
 } smb_ofile_t;
 
 /* odir flags bits */
@@ -902,7 +908,8 @@
 typedef enum {
 	SMB_ODIR_STATE_OPEN = 0,
 	SMB_ODIR_STATE_CLOSING,
-	SMB_ODIR_STATE_CLOSED
+	SMB_ODIR_STATE_CLOSED,
+	SMB_ODIR_STATE_SENTINEL
 } smb_odir_state_t;
 
 typedef struct smb_odir {
@@ -1163,7 +1170,8 @@
 	SMB_REQ_STATE_WAITING_LOCK,
 	SMB_REQ_STATE_COMPLETED,
 	SMB_REQ_STATE_CANCELED,
-	SMB_REQ_STATE_CLEANED_UP
+	SMB_REQ_STATE_CLEANED_UP,
+	SMB_REQ_STATE_SENTINEL
 } smb_req_state_t;
 
 typedef struct smb_request {
@@ -1174,6 +1182,7 @@
 	boolean_t		sr_keep;
 	kmem_cache_t		*sr_cache;
 	struct smb_server	*sr_server;
+	pid_t			*sr_pid;
 	uint32_t		sr_gmtoff;
 	smb_session_t		*session;
 	smb_kmod_cfg_t		*sr_cfg;
@@ -1263,7 +1272,7 @@
 		uint64_t	fileid;
 		uint32_t	rootdirfid;
 		/* This is only set by NTTransactCreate */
-		smb_sd_t	*sd;
+		struct smb_sd	*sd;
 	    } open;
 
 	    struct dirop {
@@ -1391,7 +1400,8 @@
 	SMB_SERVER_STATE_CREATED = 0,
 	SMB_SERVER_STATE_CONFIGURED,
 	SMB_SERVER_STATE_RUNNING,
-	SMB_SERVER_STATE_DELETING
+	SMB_SERVER_STATE_DELETING,
+	SMB_SERVER_STATE_SENTINEL
 } smb_server_state_t;
 
 typedef struct smb_server {
@@ -1401,7 +1411,7 @@
 	list_node_t		sv_lnd;
 	smb_server_state_t	sv_state;
 	uint32_t		sv_refcnt;
-	proc_t			*sv_proc;
+	pid_t			sv_pid;
 	zoneid_t		sv_zid;
 	smb_listener_daemon_t	sv_nbt_daemon;
 	smb_listener_daemon_t	sv_tcp_daemon;
@@ -1628,7 +1638,7 @@
 	smb_acehdr_t	se_hdr;
 	uint32_t	se_mask;
 	list_node_t	se_sln;
-	nt_sid_t	*se_sid;
+	smb_sid_t	*se_sid;
 } smb_ace_t;
 
 /*
@@ -1768,14 +1778,14 @@
  * the required abstraction for CIFS code.
  */
 
-struct smb_sd {
+typedef struct smb_sd {
 	uint8_t		sd_revision;
 	uint16_t	sd_control;
-	nt_sid_t 	*sd_owner;	/* SID file owner */
-	nt_sid_t 	*sd_group;	/* SID group (for POSIX) */
+	smb_sid_t 	*sd_owner;	/* SID file owner */
+	smb_sid_t 	*sd_group;	/* SID group (for POSIX) */
 	smb_acl_t 	*sd_sacl;	/* ACL System (audits) */
 	smb_acl_t 	*sd_dacl;	/* ACL Discretionary (perm) */
-};
+} smb_sd_t;
 
 /*
  * SD header size as it appears on the wire
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/smbsrv/smb_sid.h	Mon Apr 14 10:40:32 2008 -0700
@@ -0,0 +1,278 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SMB_SID_H
+#define	_SMB_SID_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * NT Security Identifier (SID) interface definition.
+ */
+#include <smbsrv/wintypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Predefined global user RIDs.
+ */
+#define	DOMAIN_USER_RID_ADMIN		(0x000001F4L)	/* 500 */
+#define	DOMAIN_USER_RID_GUEST		(0x000001F5L)	/* 501 */
+#define	DOMAIN_USER_RID_KRBTGT		(0x000001F6L)	/* 502 */
+
+/*
+ * Predefined global group RIDs.
+ */
+#define	DOMAIN_GROUP_RID_ADMINS		(0x00000200L)	/* 512 */
+#define	DOMAIN_GROUP_RID_USERS		(0x00000201L)
+#define	DOMAIN_GROUP_RID_GUESTS		(0x00000202L)
+#define	DOMAIN_GROUP_RID_COMPUTERS	(0x00000203L)
+#define	DOMAIN_GROUP_RID_CONTROLLERS	(0x00000204L)
+#define	DOMAIN_GROUP_RID_CERT_ADMINS	(0x00000205L)
+#define	DOMAIN_GROUP_RID_SCHEMA_ADMINS	(0x00000206L)
+
+
+/*
+ * Predefined local alias RIDs.
+ */
+#define	DOMAIN_ALIAS_RID_ADMINS		(0x00000220L)	/* 544 */
+#define	DOMAIN_ALIAS_RID_USERS		(0x00000221L)
+#define	DOMAIN_ALIAS_RID_GUESTS		(0x00000222L)
+#define	DOMAIN_ALIAS_RID_POWER_USERS	(0x00000223L)
+#define	DOMAIN_ALIAS_RID_ACCOUNT_OPS	(0x00000224L)
+#define	DOMAIN_ALIAS_RID_SYSTEM_OPS	(0x00000225L)
+#define	DOMAIN_ALIAS_RID_PRINT_OPS	(0x00000226L)
+#define	DOMAIN_ALIAS_RID_BACKUP_OPS	(0x00000227L)
+#define	DOMAIN_ALIAS_RID_REPLICATOR	(0x00000228L)
+
+
+/*
+ * Universal and NT well-known SIDs
+ */
+#define	NT_NULL_SIDSTR				"S-1-0-0"
+#define	NT_WORLD_SIDSTR				"S-1-1-0"
+#define	NT_LOCAL_SIDSTR				"S-1-2-0"
+#define	NT_CREATOR_OWNER_ID_SIDSTR		"S-1-3-0"
+#define	NT_CREATOR_GROUP_ID_SIDSTR		"S-1-3-1"
+#define	NT_CREATOR_OWNER_SERVER_ID_SIDSTR	"S-1-3-2"
+#define	NT_CREATOR_GROUP_SERVER_ID_SIDSTR	"S-1-3-3"
+#define	NT_NON_UNIQUE_IDS_SIDSTR		"S-1-4"
+#define	NT_AUTHORITY_SIDSTR			"S-1-5"
+#define	NT_DIALUP_SIDSTR			"S-1-5-1"
+#define	NT_NETWORK_SIDSTR			"S-1-5-2"
+#define	NT_BATCH_SIDSTR				"S-1-5-3"
+#define	NT_INTERACTIVE_SIDSTR			"S-1-5-4"
+#define	NT_SERVICE_SIDSTR			"S-1-5-6"
+#define	NT_ANONYMOUS_LOGON_SIDSTR		"S-1-5-7"
+#define	NT_PROXY_SIDSTR				"S-1-5-8"
+#define	NT_SERVER_LOGON_SIDSTR			"S-1-5-9"
+#define	NT_SELF_SIDSTR				"S-1-5-10"
+#define	NT_AUTHENTICATED_USER_SIDSTR		"S-1-5-11"
+#define	NT_RESTRICTED_CODE_SIDSTR		"S-1-5-12"
+#define	NT_LOCAL_SYSTEM_SIDSTR			"S-1-5-18"
+#define	NT_NON_UNIQUE_SIDSTR			"S-1-5-21"
+#define	NT_BUILTIN_DOMAIN_SIDSTR		"S-1-5-32"
+
+
+/*
+ * SID type indicators (SID_NAME_USE).
+ */
+#define	SidTypeNull			0
+#define	SidTypeUser			1
+#define	SidTypeGroup			2
+#define	SidTypeDomain			3
+#define	SidTypeAlias			4
+#define	SidTypeWellKnownGroup		5
+#define	SidTypeDeletedAccount		6
+#define	SidTypeInvalid			7
+#define	SidTypeUnknown			8
+#define	SidTypeComputer			9
+
+
+/*
+ * Identifier authorities for various domains.
+ */
+#define	NT_SID_NULL_AUTH		0
+#define	NT_SID_WORLD_AUTH		1
+#define	NT_SID_LOCAL_AUTH		2
+#define	NT_SID_CREATOR_AUTH		3
+#define	NT_SID_NON_UNIQUE_AUTH		4
+#define	NT_SID_NT_AUTH			5
+
+
+#define	NT_SECURITY_NULL_AUTH		{0, 0, 0, 0, 0, 0}
+#define	NT_SECURITY_WORLD_AUTH		{0, 0, 0, 0, 0, 1}
+#define	NT_SECURITY_LOCAL_AUTH		{0, 0, 0, 0, 0, 2}
+#define	NT_SECURITY_CREATOR_AUTH	{0, 0, 0, 0, 0, 3}
+#define	NT_SECURITY_NON_UNIQUE_AUTH	{0, 0, 0, 0, 0, 4}
+#define	NT_SECURITY_NT_AUTH		{0, 0, 0, 0, 0, 5}
+#define	NT_SECURITY_UNIX_AUTH		{0, 0, 0, 0, 0, 99}
+
+
+#define	SECURITY_NULL_RID			(0x00000000L)
+#define	SECURITY_WORLD_RID			(0x00000000L)
+#define	SECURITY_LOCAL_RID			(0X00000000L)
+
+#define	SECURITY_CREATOR_OWNER_RID		(0x00000000L)
+#define	SECURITY_CREATOR_GROUP_RID		(0x00000001L)
+#define	SECURITY_CREATOR_OWNER_SERVER_RID	(0x00000002L)
+#define	SECURITY_CREATOR_GROUP_SERVER_RID	(0x00000003L)
+
+#define	SECURITY_DIALUP_RID			(0x00000001L)
+#define	SECURITY_NETWORK_RID			(0x00000002L)
+#define	SECURITY_BATCH_RID			(0x00000003L)
+#define	SECURITY_INTERACTIVE_RID		(0x00000004L)
+#define	SECURITY_LOGON_IDS_RID			(0x00000005L)
+#define	SECURITY_LOGON_IDS_RID_COUNT		(3L)
+#define	SECURITY_SERVICE_RID			(0x00000006L)
+#define	SECURITY_ANONYMOUS_LOGON_RID		(0x00000007L)
+#define	SECURITY_PROXY_RID			(0x00000008L)
+#define	SECURITY_ENTERPRISE_CONTROLLERS_RID	(0x00000009L)
+#define	SECURITY_SERVER_LOGON_RID	SECURITY_ENTERPRISE_CONTROLLERS_RID
+#define	SECURITY_PRINCIPAL_SELF_RID		(0x0000000AL)
+#define	SECURITY_AUTHENTICATED_USER_RID		(0x0000000BL)
+#define	SECURITY_RESTRICTED_CODE_RID		(0x0000000CL)
+
+#define	SECURITY_LOCAL_SYSTEM_RID		(0x00000012L)
+#define	SECURITY_NT_NON_UNIQUE			(0x00000015L)
+#define	SECURITY_BUILTIN_DOMAIN_RID		(0x00000020L)
+
+
+#define	NT_SID_NON_UNIQUE_SUBAUTH 21
+
+
+/*
+ * Common definition for a SID.
+ */
+#define	NT_SID_REVISION		1
+#define	NT_SID_AUTH_MAX		6
+#define	NT_SID_SUBAUTH_MAX	15
+
+
+/*
+ * Security Identifier (SID)
+ *
+ * The security identifier (SID) uniquely identifies a user, group or
+ * a domain. It consists of a revision number, the identifier authority,
+ * and a list of sub-authorities. The revision number is currently 1.
+ * The identifier authority identifies which system issued the SID. The
+ * sub-authorities of a domain SID uniquely identify a domain. A user
+ * or group SID consists of a domain SID with the user or group id
+ * appended. The user or group id (also known as a relative id (RID)
+ * uniquely identifies a user within a domain. A user or group SID
+ * uniquely identifies a user or group across all domains. The SidType
+ * values identify the various types of SID.
+ *
+ *      1   1   1   1   1   1
+ *      5   4   3   2   1   0   9   8   7   6   5   4   3   2   1   0
+ *   +---------------------------------------------------------------+
+ *   |      SubAuthorityCount        |Reserved1 (SBZ)|   Revision    |
+ *   +---------------------------------------------------------------+
+ *   |                   IdentifierAuthority[0]                      |
+ *   +---------------------------------------------------------------+
+ *   |                   IdentifierAuthority[1]                      |
+ *   +---------------------------------------------------------------+
+ *   |                   IdentifierAuthority[2]                      |
+ *   +---------------------------------------------------------------+
+ *   |                                                               |
+ *   +- -  -  -  -  -  -  -  SubAuthority[]  -  -  -  -  -  -  -  - -+
+ *   |                                                               |
+ *   +---------------------------------------------------------------+
+ *
+ */
+/*
+ * Note: NT defines the Identifier Authority as a separate
+ * structure (SID_IDENTIFIER_AUTHORITY) containing a literal
+ * definition of a 6 byte vector but the effect is the same
+ * as defining it as a member value.
+ */
+typedef struct smb_sid {
+	uint8_t sid_revision;
+	uint8_t sid_subauthcnt;
+	uint8_t sid_authority[NT_SID_AUTH_MAX];
+	uint32_t sid_subauth[ANY_SIZE_ARRAY];
+} smb_sid_t;
+
+/*
+ * Well-known account structure
+ */
+typedef struct smb_wka {
+	uint16_t	wka_type;
+	uint8_t		wka_domidx;
+	char		*wka_sid;
+	char		*wka_name;
+	uint16_t	wka_flags;
+	char		*wka_desc;
+	smb_sid_t	*wka_binsid;
+} smb_wka_t;
+
+/*
+ * Defined values for smb_wka.wka_flags
+ *
+ * SMB_WKAFLG_LGRP_ENABLE		Can be added as local group
+ */
+#define	SMB_WKAFLG_LGRP_ENABLE	0x1
+
+/*
+ * The maximum size of a SID in string format
+ */
+#define	SMB_SID_STRSZ		256
+
+boolean_t smb_sid_isvalid(smb_sid_t *);
+int smb_sid_len(smb_sid_t *);
+smb_sid_t *smb_sid_dup(smb_sid_t *);
+smb_sid_t *smb_sid_splice(smb_sid_t *, uint32_t);
+int smb_sid_getrid(smb_sid_t *, uint32_t *);
+int smb_sid_split(smb_sid_t *, uint32_t *);
+boolean_t smb_sid_cmp(smb_sid_t *, smb_sid_t *);
+boolean_t smb_sid_islocal(smb_sid_t *);
+boolean_t smb_sid_indomain(smb_sid_t *, smb_sid_t *);
+void smb_sid_free(smb_sid_t *);
+int smb_sid_splitstr(char *, uint32_t *);
+void smb_sid_tostr(smb_sid_t *, char *);
+smb_sid_t *smb_sid_fromstr(char *);
+char *smb_sid_type2str(uint16_t);
+
+
+/*
+ * Well-known account interfaces
+ */
+int smb_wka_init(void);
+void smb_wka_fini(void);
+smb_wka_t *smb_wka_lookup(char *);
+char *smb_wka_lookup_sid(smb_sid_t *, uint16_t *);
+smb_sid_t *smb_wka_lookup_name(char *, uint16_t *);
+char *smb_wka_lookup_domain(char *);
+boolean_t smb_wka_is_wellknown(char *);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _SMB_SID_H */
--- a/usr/src/uts/common/smbsrv/smb_token.h	Mon Apr 14 10:25:34 2008 -0700
+++ b/usr/src/uts/common/smbsrv/smb_token.h	Mon Apr 14 10:40:32 2008 -0700
@@ -30,6 +30,7 @@
 
 #include <smbsrv/netrauth.h>
 #include <smbsrv/smb_privilege.h>
+#include <smbsrv/smb_sid.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -64,7 +65,7 @@
 
 typedef struct smb_sid_attrs {
 	uint32_t attrs;
-	nt_sid_t *sid;
+	smb_sid_t *sid;
 } smb_sid_attrs_t;
 
 /*
@@ -173,22 +174,22 @@
 	uint32_t primary_group_rid;
 	char *name;
 	char *domain_name;
-	nt_sid_t *domain_sid;
+	smb_sid_t *domain_sid;
 	uint32_t n_groups;
 	smb_rid_attrs_t *groups;
 	uint32_t n_other_grps;
 	smb_sid_attrs_t *other_grps;
 	smb_session_key_t *session_key;
 
-	nt_sid_t *user_sid;
-	nt_sid_t *pgrp_sid;
+	smb_sid_t *user_sid;
+	smb_sid_t *pgrp_sid;
 	uint32_t flags;
 } smb_userinfo_t;
 
 /* XDR routines */
 extern bool_t xdr_smb_session_key_t();
 extern bool_t xdr_netr_client_t();
-extern bool_t xdr_nt_sid_t();
+extern bool_t xdr_smb_sid_t();
 extern bool_t xdr_smb_sid_attrs_t();
 extern bool_t xdr_smb_id_t();
 extern bool_t xdr_smb_win_grps_t();
@@ -202,6 +203,7 @@
 uint8_t *smb_token_mkselfrel(smb_token_t *obj, uint32_t *len);
 netr_client_t *netr_client_mkabsolute(uint8_t *buf, uint32_t len);
 void netr_client_xfree(netr_client_t *);
+void smb_token_log(smb_token_t *token);
 #else /* _KERNEL */
 smb_token_t *smb_token_mkabsolute(uint8_t *buf, uint32_t len);
 void smb_token_free(smb_token_t *token);
@@ -209,13 +211,6 @@
 #endif /* _KERNEL */
 
 int smb_token_query_privilege(smb_token_t *token, int priv_id);
-/*
- * Diagnostic routines:
- * smb_token_print: write the contents of a token to the log.
- * smb_token_log: log message is prefixed with token basic info.
- */
-void smb_token_print(smb_token_t *token);
-void smb_token_log(int level, smb_dr_user_ctx_t *user_ctx, char *fmt, ...);
 
 #ifdef __cplusplus
 }