summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd.h3
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_join.c29
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_main.c11
-rwxr-xr-xusr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c25
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_nicmon.c127
-rw-r--r--usr/src/lib/libshare/smb/libshare_smb.c30
-rw-r--r--usr/src/lib/pam_modules/smb/smb_passwd.c6
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c5
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c6
-rw-r--r--usr/src/lib/smbsrv/libsmb/Makefile.com4
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h48
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/mapfile-vers32
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_info.c62
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c92
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_list.c195
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_nic.c1080
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c61
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c18
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_sqlite.h132
-rw-r--r--usr/src/lib/smbsrv/libsmbns/Makefile.com5
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/libsmbns.h33
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/mapfile-vers11
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c594
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c46
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c58
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h997
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c89
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c18
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c137
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c38
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c493
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_check_directory.c21
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_close.c32
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_open.c128
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_search.c29
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_transact.c228
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_tree.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_copy.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_create.c122
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_create_directory.c35
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_delete.c57
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_delete_directory.c20
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_dispatch.c538
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_echo.c25
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_find.c65
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_find_notify_close.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_find_unique.c23
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_flush.c23
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_forward.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_fsops.c26
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c18
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_lock_svc.c1
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_locking_andx.c36
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c7
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c32
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_move.c9
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_negotiate.c22
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c59
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c32
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c21
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c18
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c28
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_open_andx.c99
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c5
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_print.c20
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_process_exit.c14
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information.c34
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information2.c17
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c17
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_read.c69
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_rename.c27
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_rpc.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_search.c36
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_seek.c21
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_session.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c30
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_set_information.c38
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_set_information2.c19
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c20
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_find.c40
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c15
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c21
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c15
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c27
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c26
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree_connect.c46
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree_connect_andx.c29
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c9
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c15
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_vops.c22
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_write.c129
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_write_raw.c22
-rw-r--r--usr/src/uts/common/smbsrv/cifs.h2
-rw-r--r--usr/src/uts/common/smbsrv/smb_kproto.h152
-rwxr-xr-xusr/src/uts/common/smbsrv/smb_winpipe.h2
-rw-r--r--usr/src/uts/common/smbsrv/smbvar.h41
99 files changed, 3573 insertions, 3708 deletions
diff --git a/usr/src/cmd/smbsrv/smbd/smbd.h b/usr/src/cmd/smbsrv/smbd/smbd.h
index b3d448381e..a069d6ab4e 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd.h
+++ b/usr/src/cmd/smbsrv/smbd/smbd.h
@@ -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.
*/
@@ -40,6 +40,7 @@ extern "C" {
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);
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_join.c b/usr/src/cmd/smbsrv/smbd/smbd_join.c
index 5e7d76396b..7cd50ed347 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_join.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_join.c
@@ -43,13 +43,6 @@
#include <smbsrv/lsalib.h>
/*
- * Local protocol flags used to indicate which version of the
- * netlogon protocol to use when attempting to find the PDC.
- */
-#define NETLOGON_PROTO_NETLOGON 0x01
-#define NETLOGON_PROTO_SAMLOGON 0x02
-
-/*
* Maximum time to wait for a domain controller (30 seconds).
*/
#define SMB_NETLOGON_TIMEOUT 30
@@ -121,8 +114,16 @@ smbd_join(smb_joininfo_t *info)
"host principal.");
}
}
+
+ (void) smb_config_getstr(SMB_CI_DOMAIN_NAME, nbt_domain,
+ sizeof (nbt_domain));
+
(void) smb_config_set_secmode(info->mode);
(void) smb_config_setstr(SMB_CI_DOMAIN_NAME, info->domain_name);
+
+ if (strcasecmp(nbt_domain, info->domain_name))
+ smb_browser_reconfig();
+
return (NT_STATUS_SUCCESS);
}
@@ -299,8 +300,6 @@ smb_netlogon_dc_browser(void *arg)
{
boolean_t rc;
char resource_domain[SMB_PI_MAX_DOMAIN];
- int net, smb_nc_cnt;
- int protocol;
for (;;) {
(void) mutex_lock(&smb_netlogon_info.snli_locate_mtx);
@@ -318,16 +317,8 @@ smb_netlogon_dc_browser(void *arg)
smb_setdomaininfo(NULL, NULL, 0);
if (msdcs_lookup_ads(resource_domain) == 0) {
- if (smb_config_getbool(SMB_CI_DOMAIN_MEMB))
- protocol = NETLOGON_PROTO_SAMLOGON;
- else
- protocol = NETLOGON_PROTO_NETLOGON;
-
- smb_nc_cnt = smb_nic_get_num();
- for (net = 0; net < smb_nc_cnt; net++) {
- smb_netlogon_request(net, protocol,
- resource_domain);
- }
+ /* Try to locate a DC via NetBIOS */
+ smb_browser_netlogon(resource_domain);
}
rc = smb_ntdomain_is_valid(SMB_NETLOGON_TIMEOUT);
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_main.c b/usr/src/cmd/smbsrv/smbd/smbd_main.c
index ca10cabb19..b407f7bbb0 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_main.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_main.c
@@ -66,9 +66,6 @@
#define SMB_CCACHE SMB_VARRUN_DIR "/ccache"
#define SMB_DBDIR "/var/smb"
-extern void smb_netbios_name_reconfig();
-extern void smb_browser_config();
-
static int smbd_daemonize_init(void);
static void smbd_daemonize_fini(int, int);
@@ -439,6 +436,9 @@ smbd_service_init(void)
}
(void) smb_lgrp_start();
+
+ (void) smb_pwd_init();
+
return (lmshare_start());
}
@@ -469,6 +469,7 @@ smbd_service_fini(void)
smb_idmap_stop();
smb_lgrp_stop();
smbd_remove_ccache();
+ smb_pwd_fini();
}
@@ -534,9 +535,7 @@ smbd_refresh_monitor(void *arg)
* what is necessary.
*/
ads_refresh();
- smb_nic_build_info();
- (void) smb_netbios_name_reconfig();
- (void) smb_browser_config();
+ smb_nicmon_reconfig();
smbd_remove_ccache();
if (ioctl(smbd.s_drv_fd, SMB_IOC_CONFIG, &dummy) < 0) {
smbd_report("configuration update ioctl: %s",
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c b/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c
index 9f676d1d51..7b44ead3af 100755
--- a/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c
@@ -23,6 +23,7 @@
* Use is subject to license terms.
*/
+
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
@@ -228,21 +229,28 @@ smb_winpipe_request(void *cookie, char *argp, size_t arg_size,
inpipe->sp_datalen = context->inlen;
context->inlen = 0;
-
context->outcookie = 0;
context->outlen = outpipe->sp_datalen;
}
-
if (mdhin.md_call_type == SMB_RPC_TRANSACT) {
- bcopy(bufp, inpipe->sp_data, tmp_pipe.sp_datalen);
- inpipe->sp_datalen = tmp_pipe.sp_datalen;
-
+ /*
+ * Append trans data to the pipe
+ */
+ if ((tmp_pipe.sp_datalen +
+ context->inlen) > SMB_CTXT_PIPE_SZ) {
+ context->inlen = 0;
+ goto zero_exit;
+ }
+ bcopy(bufp, inpipe->sp_data + context->inlen,
+ tmp_pipe.sp_datalen);
+ inpipe->sp_datalen += tmp_pipe.sp_datalen;
context = mlrpc_process(inpipe->sp_pipeid, user_ctx);
if (context == NULL)
goto zero_exit;
context->outcookie = 0;
context->outlen = outpipe->sp_datalen;
+ context->inlen = 0;
if (outpipe->sp_datalen < mdhin.md_length)
adj_len = outpipe->sp_datalen;
if (outpipe->sp_datalen > mdhin.md_length)
@@ -252,8 +260,13 @@ smb_winpipe_request(void *cookie, char *argp, size_t arg_size,
if (mdhin.md_call_type == SMB_RPC_WRITE) {
/*
- * Append write data to the stream.
+ * Append write data to the pipe
*/
+ if ((tmp_pipe.sp_datalen +
+ context->inlen) > SMB_CTXT_PIPE_SZ) {
+ context->inlen = 0;
+ goto zero_exit;
+ }
bcopy(bufp, inpipe->sp_data + context->inlen,
tmp_pipe.sp_datalen);
inpipe->sp_datalen += tmp_pipe.sp_datalen;
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c b/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c
index 11a228da07..7a739476b1 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c
@@ -49,11 +49,10 @@
static pthread_t smb_nicmon_thread;
-static void smb_setup_rtsock(int, int *);
-static int smb_nics_changed(int);
-static void *smb_nicmonitor(void *);
-static int smb_setup_eventpipe(int *, int *);
-static void smb_process_nic_change();
+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;
@@ -66,13 +65,19 @@ smb_nicmon_start(void)
{
int rc = 0;
- smb_nic_build_info();
- rc = pthread_create(&smb_nicmon_thread, NULL, smb_nicmonitor, 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, "smb_nicmonitor: "
- "NIC monitoring failed to start: %s", strerror(errno));
+ syslog(LOG_ERR, "NIC monitor failed to start (%s)",
+ strerror(errno));
return (rc);
}
+
return (rc);
}
@@ -88,30 +93,67 @@ smb_nicmon_stop(void)
return;
(void) write(eventpipe_write, &buf, sizeof (buf));
+ smb_nic_fini();
+}
+
+/*
+ * Call this to do stuff after ifs changed.
+ */
+void
+smb_nicmon_reconfig(void)
+{
+ boolean_t ddns_enabled;
+
+ ddns_enabled = smb_config_getbool(SMB_CI_DYNDNS_ENABLE);
+
+ /* Clear rev zone before creating if list */
+ if (ddns_enabled) {
+ if (dyndns_clear_rev_zone() != 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 (dyndns_update() != 0) {
+ syslog(LOG_ERR, "smb_nicmon_daemon: "
+ "failed to update dynamic DNS");
+ }
+ }
}
/*
* Setup routing socket for getting RTM messages.
*/
static void
-smb_setup_rtsock(int af, int *s)
+smb_nicmon_setup_rtsock(int af, int *s)
{
int flags;
*s = socket(PF_ROUTE, SOCK_RAW, af);
if (*s == -1) {
- syslog(LOG_ERR, "smb_setup_rtsock: failed to "
+ syslog(LOG_ERR, "smb_nicmon_daemon: failed to "
"create routing socket");
return;
}
if ((flags = fcntl(*s, F_GETFL, 0)) < 0) {
- syslog(LOG_ERR, "smb_setup_rtsock: failed to fcntl F_GETFL");
+ 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_setup_rtsock: failed to fcntl F_SETFL");
+ syslog(LOG_ERR, "smb_nicmon_daemon: "
+ "failed to fcntl F_SETFL");
(void) close(*s);
*s = -1;
return;
@@ -119,7 +161,7 @@ smb_setup_rtsock(int af, int *s)
}
static int
-smb_nics_changed(int sock)
+smb_nicmon_needscan(int sock)
{
int nbytes;
int64_t msg[2048 / 8];
@@ -137,7 +179,7 @@ smb_nics_changed(int sock)
continue;
}
if (nbytes < rtm->rtm_msglen) {
- syslog(LOG_DEBUG, "smb_nicmonitor: short read: %d "
+ syslog(LOG_DEBUG, "smb_nicmon_daemon: short read: %d "
"of %d", nbytes, rtm->rtm_msglen);
continue;
}
@@ -160,12 +202,12 @@ smb_nics_changed(int sock)
* Create pipe for signal delivery and set up signal handlers.
*/
static int
-smb_setup_eventpipe(int *read_pipe, int *write_pipe)
+smb_nicmon_setup_eventpipe(int *read_pipe, int *write_pipe)
{
int fds[2];
if ((pipe(fds)) < 0) {
- syslog(LOG_ERR, "smb_nicmonitor: failed to open pipe");
+ syslog(LOG_ERR, "smb_nicmon_daemon: failed to open pipe");
return (1);
}
*read_pipe = fds[0];
@@ -173,41 +215,9 @@ smb_setup_eventpipe(int *read_pipe, int *write_pipe)
return (0);
}
-/*
- * Call this to do stuff after ifs changed.
- */
-static void
-smb_process_nic_change()
-{
- boolean_t ddns_enabled;
-
- ddns_enabled = smb_config_getbool(SMB_CI_DYNDNS_ENABLE);
-
- /* Clear rev zone before creating if list */
- if (ddns_enabled) {
- if (dyndns_clear_rev_zone() != 0) {
- syslog(LOG_ERR, "smb_nicmonitor: "
- "failed to clear DNS reverse lookup zone");
- }
- }
-
- /* re-initialize NIC table */
- smb_nic_build_info();
-
- smb_netbios_name_reconfig();
- smb_browser_config();
-
- if (ddns_enabled) {
- if (dyndns_update() != 0) {
- syslog(LOG_ERR, "smb_nicmonitor: "
- "failed to update dynamic DNS");
- }
- }
-}
-
/*ARGSUSED*/
static void *
-smb_nicmonitor(void *args)
+smb_nicmon_daemon(void *args)
{
struct pollfd pollfds[2];
int pollfd_num = 2;
@@ -221,13 +231,16 @@ smb_nicmonitor(void *args)
* monitor changes in NIC interfaces. We are only interested
* in new inerface addition/deletion and change in UP/DOWN status.
*/
- smb_setup_rtsock(AF_INET, &rtsock_v4);
+ smb_nicmon_setup_rtsock(AF_INET, &rtsock_v4);
if (rtsock_v4 == -1) {
- syslog(LOG_ERR, "smb_nicmonitor: cannot open routing socket");
+ syslog(LOG_ERR, "smb_nicmon_daemon: "
+ "cannot open routing socket");
return (NULL);
}
- if (smb_setup_eventpipe(&eventpipe_read, &eventpipe_write) != 0) {
- syslog(LOG_ERR, "smb_nicmonitor: cannot open event pipes");
+
+ if (smb_nicmon_setup_eventpipe(&eventpipe_read, &eventpipe_write)
+ != 0) {
+ syslog(LOG_ERR, "smb_nicmon_daemon: cannot open event pipes");
return (NULL);
}
@@ -243,7 +256,7 @@ smb_nicmonitor(void *args)
if (poll(pollfds, pollfd_num, -1) < 0) {
if (errno == EINTR)
continue;
- syslog(LOG_ERR, "smb_nicmonitor: "
+ syslog(LOG_ERR, "smb_nicmon_daemon: "
"poll failed with errno %d", errno);
break;
}
@@ -252,7 +265,7 @@ smb_nicmonitor(void *args)
!(pollfds[i].revents & POLLIN))
continue;
if (pollfds[i].fd == rtsock_v4)
- nic_changed = smb_nics_changed(rtsock_v4);
+ nic_changed = smb_nicmon_needscan(rtsock_v4);
if (pollfds[i].fd == eventpipe_read)
goto done;
}
@@ -262,7 +275,7 @@ smb_nicmonitor(void *args)
* nic list and other configs.
*/
if (nic_changed)
- smb_process_nic_change();
+ smb_nicmon_reconfig();
}
done:
/* Close sockets */
diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c
index 1b1fa9baf5..c73abfa732 100644
--- a/usr/src/lib/libshare/smb/libshare_smb.c
+++ b/usr/src/lib/libshare/smb/libshare_smb.c
@@ -293,6 +293,25 @@ smb_isautoenable(void)
}
/*
+ * smb_ismaint()
+ *
+ * Determine if the SMF service instance is in the disabled state or
+ * not. A number of operations depend on this state.
+ */
+static boolean_t
+smb_ismaint(void)
+{
+ char *str;
+ boolean_t ret = B_FALSE;
+
+ if ((str = smf_get_state(SMBD_DEFAULT_INSTANCE_FMRI)) != NULL) {
+ ret = (strcmp(str, SCF_STATE_STRING_MAINT) == 0);
+ free(str);
+ }
+ return (ret);
+}
+
+/*
* smb_enable_share tells the implementation that it is to enable the share.
* This entails converting the path and options into the appropriate ioctl
* calls. It is assumed that all error checking of paths, etc. were
@@ -361,7 +380,7 @@ smb_enable_share(sa_share_t share)
* For now, it is OK to not be able to enable
* the service.
*/
- if (err == SA_BUSY)
+ if (err == SA_BUSY || err == SA_SYSTEM_ERR)
err = SA_OK;
} else {
online = B_TRUE;
@@ -1233,7 +1252,16 @@ smb_enable_service(void)
if (smb_isonline()) {
ret = SA_OK;
break;
+ } else if (smb_ismaint()) {
+ /* maintenance requires help */
+ ret = SA_SYSTEM_ERR;
+ break;
+ } else if (smb_isdisabled()) {
+ /* disabled is ok */
+ ret = SA_OK;
+ break;
} else {
+ /* try another time */
ret = SA_BUSY;
(void) sleep(1);
}
diff --git a/usr/src/lib/pam_modules/smb/smb_passwd.c b/usr/src/lib/pam_modules/smb/smb_passwd.c
index 9167d093a6..4e484251e3 100644
--- a/usr/src/lib/pam_modules/smb/smb_passwd.c
+++ b/usr/src/lib/pam_modules/smb/smb_passwd.c
@@ -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.
*/
@@ -145,8 +145,12 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
return (PAM_SYSTEM_ERR);
}
+ smb_pwd_init();
+
res = smb_pwd_setpasswd(user, newpw);
+ smb_pwd_fini();
+
/*
* now map the various return states to user messages
* and PAM return codes.
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
index a1f203c09c..656bda3cf8 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
@@ -55,7 +55,6 @@ static unsigned long mlrpc_frag_size = MLRPC_FRAG_SZ;
/*
* Context table.
*/
-#define CTXT_PIPE_SZ 65536
#define CTXT_TABLE_ENTRIES 128
static struct mlsvc_rpc_context context_table[CTXT_TABLE_ENTRIES];
static mutex_t mlrpc_context_lock;
@@ -167,8 +166,8 @@ mlrpc_lookup(int fid)
if (available) {
bzero(available, sizeof (struct mlsvc_rpc_context));
- available->inpipe = malloc(CTXT_PIPE_SZ);
- available->outpipe = malloc(CTXT_PIPE_SZ);
+ available->inpipe = malloc(SMB_CTXT_PIPE_SZ);
+ available->outpipe = malloc(SMB_CTXT_PIPE_SZ);
if (available->inpipe == NULL || available->outpipe == NULL) {
free(available->inpipe);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
index 0bc4206f3d..7820c47593 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
@@ -313,7 +313,7 @@ lsarpc_s_OpenAccount(void *arg, struct mlrpc_xaction *mxa)
hd = ndr_hdlookup(mxa, id);
if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
- bzero(&param, sizeof (struct mslsa_OpenAccount));
+ bzero(param, sizeof (struct mslsa_OpenAccount));
param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c
index 242fdbc75f..0b44de942f 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c
@@ -255,7 +255,7 @@ svcctl_s_QueryServiceStatus(void *arg, struct mlrpc_xaction *mxa)
hd = ndr_hdlookup(mxa, id);
if ((hd == NULL) || (hd->nh_data != &svcctl_key_service)) {
- bzero(&param, sizeof (struct svcctl_QueryServiceStatus));
+ bzero(param, sizeof (struct svcctl_QueryServiceStatus));
param->status = ERROR_INVALID_HANDLE;
return (MLRPC_DRC_OK);
}
@@ -298,7 +298,7 @@ svcctl_s_EnumServicesStatus(void *arg, struct mlrpc_xaction *mxa)
hd = ndr_hdlookup(mxa, id);
if ((hd == NULL) || (hd->nh_data != &svcctl_key_manager)) {
- bzero(&param, sizeof (struct svcctl_EnumServicesStatus));
+ bzero(param, sizeof (struct svcctl_EnumServicesStatus));
param->status = ERROR_INVALID_HANDLE;
return (MLRPC_DRC_OK);
}
@@ -371,7 +371,7 @@ svcctl_s_QueryServiceConfig(void *arg, struct mlrpc_xaction *mxa)
hd = ndr_hdlookup(mxa, id);
if ((hd == NULL) || (hd->nh_data != &svcctl_key_service)) {
- bzero(&param, sizeof (struct svcctl_QueryServiceConfig));
+ bzero(param, sizeof (struct svcctl_QueryServiceConfig));
param->status = ERROR_INVALID_HANDLE;
return (MLRPC_DRC_OK);
}
diff --git a/usr/src/lib/smbsrv/libsmb/Makefile.com b/usr/src/lib/smbsrv/libsmb/Makefile.com
index 857605eb72..7573c93e12 100644
--- a/usr/src/lib/smbsrv/libsmb/Makefile.com
+++ b/usr/src/lib/smbsrv/libsmb/Makefile.com
@@ -59,8 +59,10 @@ OBJS_COMMON = \
smb_ht.o \
smb_idmap.o \
smb_info.o \
+ smb_list.o \
smb_lgrp.o \
smb_mac.o \
+ smb_nic.o \
smb_pwdutil.o \
smb_privilege.o \
smb_scfutil.o \
@@ -76,7 +78,7 @@ include ../../Makefile.lib
INCS += -I$(SRC)/common/smbsrv
LDLIBS += $(MACH_LDLIBS)
-LDLIBS += -lscf -lmd -lnsl -lpkcs11 -lc -lresolv -lidmap
+LDLIBS += -lscf -lmd -lnsl -lpkcs11 -lc -lsocket -lresolv -lidmap
CPPFLAGS += $(INCS) -D_REENTRANT
SRCS= $(OBJS_COMMON:%.o=$(SRCDIR)/%.c) \
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index 50a3c3d989..b6232a5844 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -33,7 +33,9 @@ extern "C" {
#endif
#include <sys/types.h>
+#include <sys/list.h>
#include <arpa/inet.h>
+#include <net/if.h>
#include <netdb.h>
#include <stdlib.h>
@@ -43,6 +45,7 @@ extern "C" {
#include <smbsrv/string.h>
#include <smbsrv/smb_idmap.h>
+#include <smbsrv/netbios.h>
/*
* XXX - These header files are here, only because other libraries
@@ -280,6 +283,10 @@ extern int smb_gethostname(char *, size_t, int);
extern int smb_getfqhostname(char *, size_t);
extern int smb_getnetbiosname(char *, size_t);
+extern int smb_get_nameservers(struct in_addr *, int);
+extern void smb_tonetbiosname(char *, char *, char);
+
+
void smb_trace(const char *s);
void smb_tracef(const char *fmt, ...);
@@ -430,6 +437,8 @@ typedef struct smb_passwd {
#define SMB_PWE_SYSTEM_ERROR 11
#define SMB_PWE_MAX 12
+extern void smb_pwd_init(void);
+extern void smb_pwd_fini(void);
extern smb_passwd_t *smb_pwd_getpasswd(const char *, smb_passwd_t *);
extern int smb_pwd_setpasswd(const char *, const char *);
extern int smb_pwd_setcntl(const char *, int);
@@ -665,6 +674,45 @@ int smb_lookup_name(char *, smb_gsid_t *);
#define SMB_LGRP_COMMENT_MAX 256
#define SMB_LGRP_NAME_MAX (SMB_LGRP_NAME_CHAR_MAX * MTS_MB_CHAR_MAX + 1)
+/*
+ * values for smb_nic_t.smbflags
+ */
+#define SMB_NICF_NBEXCL 0x01 /* Excluded from Netbios activities */
+#define SMB_NICF_ALIAS 0x02 /* This is an alias */
+
+/*
+ * smb_nic_t
+ * nic_host actual host name
+ * nic_nbname 16-byte NetBIOS host name
+ */
+typedef struct {
+ char nic_host[MAXHOSTNAMELEN];
+ char nic_nbname[NETBIOS_NAME_SZ];
+ char nic_cmnt[SMB_PI_MAX_COMMENT];
+ char nic_ifname[LIFNAMSIZ];
+ uint32_t nic_ip;
+ uint32_t nic_mask;
+ uint32_t nic_bcast;
+ uint32_t nic_smbflags;
+ uint64_t nic_sysflags;
+} smb_nic_t;
+
+typedef struct smb_niciter {
+ smb_nic_t ni_nic;
+ int ni_cookie;
+ int ni_seqnum;
+} smb_niciter_t;
+
+/* NIC config functions */
+int smb_nic_init(void);
+void smb_nic_fini(void);
+int smb_nic_getnum(char *);
+int smb_nic_addhost(const char *, const char *, int, const char **);
+int smb_nic_delhost(const char *);
+int smb_nic_getfirst(smb_niciter_t *);
+int smb_nic_getnext(smb_niciter_t *);
+boolean_t smb_nic_exists(uint32_t, boolean_t);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
index 20d808c588..7efbabcaec 100644
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
@@ -48,6 +48,20 @@ SUNWprivate {
ht_remove_item;
ht_replace_item;
ht_set_cmpfn;
+ list_create;
+ list_destroy;
+ list_head;
+ list_insert_after;
+ list_insert_before;
+ list_insert_head;
+ list_insert_tail;
+ list_is_empty;
+ list_link_active;
+ list_move_tail;
+ list_next;
+ list_prev;
+ list_remove;
+ list_tail;
smb_msgbuf_base;
smb_msgbuf_decode;
smb_msgbuf_dword_align;
@@ -184,6 +198,7 @@ SUNWprivate {
smb_dwncall_install_callback;
smb_dwncall_share;
smb_dwncall_user_num;
+ smb_get_nameservers;
smb_getdomaininfo;
smb_getdomainname;
smb_getfqdomainname;
@@ -233,6 +248,14 @@ SUNWprivate {
smb_match83;
smb_match;
smb_match_ci;
+ smb_nic_addhost;
+ smb_nic_delhost;
+ smb_nic_exists;
+ smb_nic_fini;
+ smb_nic_getfirst;
+ smb_nic_getnext;
+ smb_nic_getnum;
+ smb_nic_init;
smb_priv_getbyname;
smb_priv_getbyvalue;
smb_priv_presentable_ids;
@@ -247,11 +270,14 @@ SUNWprivate {
smb_privset_query;
smb_privset_size;
smb_privset_validate;
+ smb_tonetbiosname;
smb_trace;
smb_tracef;
- smb_pwd_getpasswd;
- smb_pwd_setcntl;
- smb_pwd_setpasswd;
+ smb_pwd_fini;
+ smb_pwd_getpasswd = AUXILIARY libsmb_pwd.so;
+ smb_pwd_init;
+ smb_pwd_setcntl = AUXILIARY libsmb_pwd.so;
+ smb_pwd_setpasswd = AUXILIARY libsmb_pwd.so;
smb_resolve_fqdn;
smb_resolve_netbiosname;
smb_setdomaininfo;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_info.c b/usr/src/lib/smbsrv/libsmb/common/smb_info.c
index 918cc02acb..0bc21f71a0 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_info.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_info.c
@@ -440,3 +440,65 @@ smb_trace(const char *s)
{
syslog(LOG_DEBUG, "%s", s);
}
+
+/*
+ * smb_tonetbiosname
+ *
+ * Creates a NetBIOS name based on the given name and suffix.
+ * NetBIOS name is 15 capital characters, padded with space if needed
+ * and the 16th byte is the suffix.
+ */
+void
+smb_tonetbiosname(char *name, char *nb_name, char suffix)
+{
+ char tmp_name[NETBIOS_NAME_SZ];
+ mts_wchar_t wtmp_name[NETBIOS_NAME_SZ];
+ unsigned int cpid;
+ int len;
+ size_t rc;
+
+ len = 0;
+ rc = mts_mbstowcs(wtmp_name, (const char *)name, NETBIOS_NAME_SZ);
+
+ if (rc != (size_t)-1) {
+ wtmp_name[NETBIOS_NAME_SZ - 1] = 0;
+ cpid = oem_get_smb_cpid();
+ rc = unicodestooems(tmp_name, wtmp_name, NETBIOS_NAME_SZ, cpid);
+ if (rc > 0)
+ len = strlen(tmp_name);
+ }
+
+ (void) memset(nb_name, ' ', NETBIOS_NAME_SZ - 1);
+ if (len) {
+ (void) utf8_strupr(tmp_name);
+ (void) memcpy(nb_name, tmp_name, len);
+ }
+ nb_name[NETBIOS_NAME_SZ - 1] = suffix;
+}
+
+int
+smb_get_nameservers(struct in_addr *ips, int sz)
+{
+ union res_sockaddr_union set[MAXNS];
+ int i, cnt;
+ struct __res_state res_state;
+
+ if (ips == NULL)
+ return (0);
+
+ bzero(&res_state, sizeof (struct __res_state));
+ if (res_ninit(&res_state) < 0)
+ return (0);
+
+ cnt = res_getservers(&res_state, set, MAXNS);
+ for (i = 0; i < cnt; i++) {
+ if (i >= sz)
+ break;
+ ips[i] = set[i].sin.sin_addr;
+ syslog(LOG_DEBUG, "NS Found %s name server\n",
+ inet_ntoa(ips[i]));
+ }
+ syslog(LOG_DEBUG, "NS Found %d name servers\n", i);
+ res_ndestroy(&res_state);
+ return (i);
+}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
index 934b804dcd..f363bc9a32 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
@@ -35,6 +35,7 @@
#include <assert.h>
#include <libintl.h>
#include <smbsrv/libsmb.h>
+#include <smb_sqlite.h>
#define SMB_LGRP_LOCAL_IDX 0
#define SMB_LGRP_BUILTIN_IDX 1
@@ -177,97 +178,6 @@ 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 **);
-#ifdef _LP64
-/*
- * We cannot make 64-bit version of libsqlite because the code
- * has some problems.
- */
-
-/*ARGSUSED*/
-sqlite *
-sqlite_open(const char *filename, int mode, char **errmsg)
-{
- return (NULL);
-}
-
-/*ARGSUSED*/
-void
-sqlite_close(sqlite *db)
-{
-}
-
-/*ARGSUSED*/
-char *
-sqlite_mprintf(const char *fmt, ...)
-{
- return (NULL);
-}
-
-/*ARGSUSED*/
-void
-sqlite_freemem(void *p)
-{
-}
-
-/*ARGSUSED*/
-int
-sqlite_compile(sqlite *db, const char *zSql, const char **pzTail,
- sqlite_vm **ppVm, char **pzErrmsg)
-{
- return (SQLITE_ERROR);
-}
-
-/*ARGSUSED*/
-void
-sqlite_free_table(char **res)
-{
-}
-
-/*ARGSUSED*/
-int
-sqlite_last_insert_rowid(sqlite *db)
-{
- return (-1);
-}
-
-/*ARGSUSED*/
-void
-sqlite_busy_timeout(sqlite *db, int ms)
-{
-}
-
-/*ARGSUSED*/
-int
-sqlite_get_table(sqlite *db, const char *zSql, char ***pazResult, int *pnRow,
- int *pnColumn, char **pzErrMsg)
-{
- return (SQLITE_ERROR);
-}
-
-/*ARGSUSED*/
-int
-sqlite_step(sqlite_vm *pVm, int *pN, const char ***pazValue,
- const char ***pazColName)
-{
- return (SQLITE_ERROR);
-}
-
-/*ARGSUSED*/
-int
-sqlite_exec(sqlite *db, const char *zSql, sqlite_callback xCallback, void *pArg,
- char **pzErrMsg)
-{
- return (SQLITE_ERROR);
-}
-
-/*ARGSUSED*/
-int
-sqlite_finalize(sqlite_vm *pVm, char **pzErrMsg)
-{
- return (SQLITE_ERROR);
-}
-#endif /* _LP64 */
-
/*
* smb_lgrp_add
*
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_list.c b/usr/src/lib/smbsrv/libsmb/common/smb_list.c
new file mode 100644
index 0000000000..db891ffb2f
--- /dev/null
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_list.c
@@ -0,0 +1,195 @@
+/*
+ * 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"
+
+/*
+ * Generic doubly-linked list implementation
+ */
+
+#include <sys/list.h>
+#include <sys/list_impl.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/debug.h>
+#include <assert.h>
+
+#define list_d2l(a, obj) ((void *)(((char *)obj) + (a)->list_offset))
+#define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
+#define list_empty(a) ((a)->list_head.list_next == &(a)->list_head)
+
+#define list_insert_after_node(list, node, object) { \
+ list_node_t *lnew = list_d2l(list, object); \
+ lnew->list_prev = node; \
+ lnew->list_next = node->list_next; \
+ node->list_next->list_prev = lnew; \
+ node->list_next = lnew; \
+}
+
+#define list_insert_before_node(list, node, object) { \
+ list_node_t *lnew = list_d2l(list, object); \
+ lnew->list_next = node; \
+ lnew->list_prev = node->list_prev; \
+ node->list_prev->list_next = lnew; \
+ node->list_prev = lnew; \
+}
+
+void
+list_create(list_t *list, size_t size, size_t offset)
+{
+ assert(list);
+ assert(size > 0);
+ assert(size >= offset + sizeof (list_node_t));
+
+ list->list_size = size;
+ list->list_offset = offset;
+ list->list_head.list_next = list->list_head.list_prev =
+ &list->list_head;
+}
+
+void
+list_destroy(list_t *list)
+{
+ list_node_t *node = &list->list_head;
+
+ assert(list);
+ assert(list->list_head.list_next == node);
+ assert(list->list_head.list_prev == node);
+
+ node->list_next = node->list_prev = NULL;
+}
+
+void
+list_insert_after(list_t *list, void *object, void *nobject)
+{
+ list_node_t *lold = list_d2l(list, object);
+ list_insert_after_node(list, lold, nobject);
+}
+
+void
+list_insert_before(list_t *list, void *object, void *nobject)
+{
+ list_node_t *lold = list_d2l(list, object);
+ list_insert_before_node(list, lold, nobject)
+}
+
+void
+list_insert_head(list_t *list, void *object)
+{
+ list_node_t *lold = &list->list_head;
+ list_insert_after_node(list, lold, object);
+}
+
+void
+list_insert_tail(list_t *list, void *object)
+{
+ list_node_t *lold = &list->list_head;
+ list_insert_before_node(list, lold, object);
+}
+
+void
+list_remove(list_t *list, void *object)
+{
+ list_node_t *lold = list_d2l(list, object);
+ assert(!list_empty(list));
+ assert(lold->list_next != NULL);
+ lold->list_prev->list_next = lold->list_next;
+ lold->list_next->list_prev = lold->list_prev;
+ lold->list_next = lold->list_prev = NULL;
+}
+
+void *
+list_head(list_t *list)
+{
+ if (list_empty(list))
+ return (NULL);
+ return (list_object(list, list->list_head.list_next));
+}
+
+void *
+list_tail(list_t *list)
+{
+ if (list_empty(list))
+ return (NULL);
+ return (list_object(list, list->list_head.list_prev));
+}
+
+void *
+list_next(list_t *list, void *object)
+{
+ list_node_t *node = list_d2l(list, object);
+
+ if (node->list_next != &list->list_head)
+ return (list_object(list, node->list_next));
+
+ return (NULL);
+}
+
+void *
+list_prev(list_t *list, void *object)
+{
+ list_node_t *node = list_d2l(list, object);
+
+ if (node->list_prev != &list->list_head)
+ return (list_object(list, node->list_prev));
+
+ return (NULL);
+}
+
+/*
+ * Insert src list after dst list. Empty src list thereafter.
+ */
+void
+list_move_tail(list_t *dst, list_t *src)
+{
+ list_node_t *dstnode = &dst->list_head;
+ list_node_t *srcnode = &src->list_head;
+
+ assert(dst->list_size == src->list_size);
+ assert(dst->list_offset == src->list_offset);
+
+ if (list_empty(src))
+ return;
+
+ dstnode->list_prev->list_next = srcnode->list_next;
+ srcnode->list_next->list_prev = dstnode->list_prev;
+ dstnode->list_prev = srcnode->list_prev;
+ srcnode->list_prev->list_next = dstnode;
+
+ /* empty src list */
+ srcnode->list_next = srcnode->list_prev = srcnode;
+}
+
+int
+list_link_active(list_node_t *link)
+{
+ return (link->list_next != NULL);
+}
+
+int
+list_is_empty(list_t *list)
+{
+ return (list_empty(list));
+}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_nic.c b/usr/src/lib/smbsrv/libsmb/common/smb_nic.c
new file mode 100644
index 0000000000..2799df5697
--- /dev/null
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_nic.c
@@ -0,0 +1,1080 @@
+/*
+ * 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"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <libintl.h>
+#include <strings.h>
+#include <string.h>
+#include <unistd.h>
+#include <synch.h>
+#include <stropts.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <inet/ip.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <net/route.h>
+#include <arpa/inet.h>
+
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/systeminfo.h>
+
+#include <smbsrv/libsmb.h>
+
+#define SMB_NIC_DB_NAME "/var/smb/smbhosts.db"
+#define SMB_NIC_DB_TIMEOUT 3000 /* in millisecond */
+#define SMB_NIC_DB_VERMAJOR 1
+#define SMB_NIC_DB_VERMINOR 0
+#define SMB_NIC_DB_MAGIC 0x484F5354 /* HOST */
+
+#define SMB_NIC_DB_ORD 1 /* open read-only */
+#define SMB_NIC_DB_ORW 2 /* open read/write */
+
+#define SMB_NIC_DB_SQL \
+ "CREATE TABLE db_info (" \
+ " ver_major INTEGER," \
+ " ver_minor INTEGER," \
+ " magic INTEGER" \
+ ");" \
+ "" \
+ "CREATE TABLE hosts (" \
+ " hostname TEXT PRIMARY KEY," \
+ " comment TEXT," \
+ " ifnames TEXT" \
+ ");"
+
+#define SMB_NIC_HTBL_NCOL 3
+#define SMB_NIC_HTBL_HOST 0
+#define SMB_NIC_HTBL_CMNT 1
+#define SMB_NIC_HTBL_IFS 2
+
+#define NULL_MSGCHK(msg) ((msg) ? (msg) : "NULL")
+
+#define SMB_NIC_MAXIFS 256
+
+typedef struct smb_hostifs {
+ list_node_t if_lnd;
+ char if_host[MAXHOSTNAMELEN];
+ char if_cmnt[SMB_PI_MAX_COMMENT];
+ char *if_names[SMB_NIC_MAXIFS];
+ int if_num;
+} smb_hostifs_t;
+
+typedef struct smb_hosts {
+ list_t h_list;
+ int h_num;
+ int h_ifnum;
+} smb_hosts_t;
+
+typedef struct {
+ smb_nic_t *nl_nics;
+ int nl_cnt; /* number of smb_nic_t structures */
+ int nl_hcnt; /* number of host names */
+ long nl_seqnum; /* a random sequence number */
+ rwlock_t nl_rwl;
+} smb_niclist_t;
+
+static int smb_nic_list_create(void);
+static void smb_nic_list_destroy(void);
+
+static int smb_nic_hlist_create(smb_hosts_t *);
+static void smb_nic_hlist_destroy(smb_hosts_t *);
+static int smb_nic_hlist_dbget(smb_hosts_t *);
+static int smb_nic_hlist_sysget(smb_hosts_t *);
+
+static void smb_nic_iflist_destroy(smb_hostifs_t *);
+static smb_hostifs_t *smb_nic_iflist_decode(const char **);
+
+static int smb_nic_dbcreate(void);
+static sqlite *smb_nic_dbopen(int);
+static void smb_nic_dbclose(sqlite *);
+static boolean_t smb_nic_dbexists(void);
+static boolean_t smb_nic_dbvalidate(void);
+static int smb_nic_dbaddhost(const char *, const char *, char *);
+static int smb_nic_dbdelhost(const char *);
+static int smb_nic_dbsetinfo(sqlite *);
+
+static int smb_nic_getinfo(char *, smb_nic_t *);
+
+/* This is the list we will monitor */
+static smb_niclist_t smb_niclist;
+
+/*
+ * smb_nic_init
+ *
+ * Initializes the interface list.
+ */
+int
+smb_nic_init(void)
+{
+ int rc;
+
+ (void) rw_wrlock(&smb_niclist.nl_rwl);
+ smb_nic_list_destroy();
+ rc = smb_nic_list_create();
+ (void) rw_unlock(&smb_niclist.nl_rwl);
+
+ return (rc);
+}
+
+/*
+ * smb_nic_fini
+ *
+ * Destroys the interface list.
+ */
+void
+smb_nic_fini(void)
+{
+ (void) rw_wrlock(&smb_niclist.nl_rwl);
+ smb_nic_list_destroy();
+ (void) rw_unlock(&smb_niclist.nl_rwl);
+}
+
+/*
+ * smb_nic_getnum
+ *
+ * Gets the number of interfaces for the specified host.
+ * if host is NULL then total number of interfaces
+ * is returned. It's assumed that given name is a NetBIOS
+ * encoded name.
+ */
+int
+smb_nic_getnum(char *nb_hostname)
+{
+ int n = 0, i;
+
+ (void) rw_rdlock(&smb_niclist.nl_rwl);
+
+ if (nb_hostname != NULL) {
+ for (i = 0; i < smb_niclist.nl_cnt; i++) {
+ /* ignore the suffix */
+ if (strncasecmp(smb_niclist.nl_nics[i].nic_nbname,
+ nb_hostname, NETBIOS_NAME_SZ - 1) == 0)
+ n++;
+ }
+ } else {
+ n = smb_niclist.nl_cnt;
+ }
+
+ (void) rw_unlock(&smb_niclist.nl_rwl);
+
+ return (n);
+}
+
+/*
+ * smb_nic_getfirst
+ *
+ * Returns the first NIC in the interface list and
+ * initializes the given iterator. To get the rest of
+ * NICs smb_nic_getnext() must be called.
+ *
+ * Returns 0 upon success and -1 if there's no interface
+ * available or if 'ni' is NULL.
+ */
+int
+smb_nic_getfirst(smb_niciter_t *ni)
+{
+ int rc = 0;
+
+ if (ni == NULL)
+ return (-1);
+
+ (void) rw_rdlock(&smb_niclist.nl_rwl);
+
+ if (smb_niclist.nl_cnt > 0) {
+ ni->ni_nic = smb_niclist.nl_nics[0];
+ ni->ni_cookie = 1;
+ ni->ni_seqnum = smb_niclist.nl_seqnum;
+ } else {
+ rc = -1;
+ }
+
+ (void) rw_unlock(&smb_niclist.nl_rwl);
+
+ return (rc);
+}
+
+/*
+ * smb_nic_getnext
+ *
+ * Returns the next NIC information based on the passed
+ * iterator (ni). The iterator must have previously been
+ * initialized by calling smb_nic_getfirst().
+ *
+ * Returns 0 upon successfully finding the specified NIC.
+ * Returns -1 if:
+ * - the specified iterator is invalid
+ * - reaches the end of the NIC list
+ * - sequence number in the iterator is different from
+ * the sequence number in the NIC list which means
+ * the list has been changed between getfirst/getnext
+ * calls.
+ */
+int
+smb_nic_getnext(smb_niciter_t *ni)
+{
+ int rc = 0;
+
+ if ((ni == NULL) || (ni->ni_cookie < 1))
+ return (-1);
+
+ (void) rw_rdlock(&smb_niclist.nl_rwl);
+
+ if ((smb_niclist.nl_cnt > ni->ni_cookie) &&
+ (smb_niclist.nl_seqnum == ni->ni_seqnum)) {
+ ni->ni_nic = smb_niclist.nl_nics[ni->ni_cookie];
+ ni->ni_cookie++;
+ } else {
+ rc = -1;
+ }
+
+ (void) rw_unlock(&smb_niclist.nl_rwl);
+
+ return (rc);
+}
+
+/*
+ * smb_nic_exists
+ *
+ * Check to see if there's a NIC with the given IP address
+ * in the list. Subnet mask will be applied when comparing the
+ * IPs if the use_mask arg is true.
+ */
+boolean_t
+smb_nic_exists(uint32_t ipaddr, boolean_t use_mask)
+{
+ smb_nic_t *cfg;
+ uint32_t mask = 0xFFFFFFFF;
+ int i;
+
+ (void) rw_rdlock(&smb_niclist.nl_rwl);
+
+ for (i = 0; i < smb_niclist.nl_cnt; i++) {
+ cfg = &smb_niclist.nl_nics[i];
+ if (use_mask)
+ mask = cfg->nic_mask;
+
+ if ((ipaddr & mask) == (cfg->nic_ip & mask)) {
+ (void) rw_unlock(&smb_niclist.nl_rwl);
+ return (B_TRUE);
+ }
+ }
+
+ (void) rw_unlock(&smb_niclist.nl_rwl);
+
+ return (B_FALSE);
+}
+
+/*
+ * smb_nic_addhost
+ *
+ * Adds an association between the given host and the specified interface
+ * list (if_names). This function can be called as many times as needed,
+ * the associations will be stored in /var/smb/smbhosts.db, which is sqlite
+ * database. If this file exists and it's not empty NIC list is generated
+ * based on the information stored in this file.
+ *
+ * host: actual system's name (not Netbios name)
+ * cmnt: an optional description for the CIFS server running on
+ * the specified host. Can be NULL.
+ * if_num: number of interface names in if_names arg
+ * if_names: array of interface names in string format
+ *
+ * Returns 0 upon success and -1 when fails
+ */
+int
+smb_nic_addhost(const char *host, const char *cmnt,
+ int if_num, const char **if_names)
+{
+ char *if_list;
+ char *ifname;
+ int buflen = 0;
+ int rc, i;
+
+ if ((host == NULL) || (if_num <= 0) || (if_names == NULL))
+ return (-1);
+
+ if (!smb_nic_dbexists() || !smb_nic_dbvalidate()) {
+ if (smb_nic_dbcreate() != SQLITE_OK)
+ return (-1);
+ }
+
+ ifname = (char *)if_names;
+ for (i = 0; i < if_num; i++, ifname++) {
+ if ((ifname == NULL) || (*ifname == '\0'))
+ return (-1);
+ buflen += strlen(ifname) + 1;
+ }
+
+ if ((if_list = malloc(buflen)) == NULL)
+ return (-1);
+
+ ifname = if_list;
+ for (i = 0; i < if_num - 1; i++)
+ ifname += snprintf(ifname, buflen, "%s,", if_names[i]);
+
+ (void) snprintf(ifname, buflen, "%s", if_names[i]);
+
+ rc = smb_nic_dbaddhost(host, cmnt, if_list);
+ free(if_list);
+
+ return ((rc == SQLITE_OK) ? 0 : -1);
+}
+
+/*
+ * smb_nic_delhost
+ *
+ * Removes the stored interface association for the specified host
+ */
+int
+smb_nic_delhost(const char *host)
+{
+ if ((host == NULL) || (*host == '\0'))
+ return (-1);
+
+ if (!smb_nic_dbexists())
+ return (0);
+
+ if (!smb_nic_dbvalidate()) {
+ (void) unlink(SMB_NIC_DB_NAME);
+ return (0);
+ }
+
+ if (smb_nic_dbdelhost(host) != SQLITE_OK)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * smb_nic_list_create
+ *
+ * Creates a NIC list either based on /var/smb/smbhosts.db or
+ * by getting the information from OS.
+ *
+ * Note that the caller of this function should grab the
+ * list lock.
+ */
+static int
+smb_nic_list_create(void)
+{
+ smb_hosts_t hlist;
+ smb_hostifs_t *iflist;
+ smb_nic_t *nc;
+ char *ifname;
+ char excludestr[MAX_EXCLUDE_LIST_LEN];
+ ipaddr_t exclude[SMB_PI_MAX_NETWORKS];
+ int nexclude;
+ int i;
+
+ if (smb_nic_hlist_create(&hlist) < 0)
+ return (-1);
+
+ smb_niclist.nl_cnt = 0;
+ smb_niclist.nl_seqnum = random();
+ smb_niclist.nl_hcnt = hlist.h_num;
+
+ smb_niclist.nl_nics = calloc(hlist.h_ifnum, sizeof (smb_nic_t));
+ if (smb_niclist.nl_nics == NULL) {
+ smb_nic_hlist_destroy(&hlist);
+ return (-1);
+ }
+
+ (void) smb_config_getstr(SMB_CI_WINS_EXCL, excludestr,
+ sizeof (excludestr));
+ nexclude = smb_wins_iplist(excludestr, exclude, SMB_PI_MAX_NETWORKS);
+
+ nc = smb_niclist.nl_nics;
+ iflist = list_head(&hlist.h_list);
+
+ do {
+ for (i = 0; i < iflist->if_num; i++) {
+ ifname = iflist->if_names[i];
+ if (smb_nic_getinfo(ifname, nc) < 0)
+ continue;
+
+ (void) strlcpy(nc->nic_host, iflist->if_host,
+ sizeof (nc->nic_host));
+ (void) strlcpy(nc->nic_cmnt, iflist->if_cmnt,
+ sizeof (nc->nic_cmnt));
+
+ smb_tonetbiosname(nc->nic_host, nc->nic_nbname, 0x00);
+
+ if (strchr(ifname, ':'))
+ nc->nic_smbflags |= SMB_NICF_ALIAS;
+
+ if (smb_wins_is_excluded(nc->nic_ip,
+ (ipaddr_t *)exclude, nexclude))
+ nc->nic_smbflags |= SMB_NICF_NBEXCL;
+
+ smb_niclist.nl_cnt++;
+ nc++;
+ }
+ } while ((iflist = list_next(&hlist.h_list, iflist)) != NULL);
+
+ smb_nic_hlist_destroy(&hlist);
+
+ if (smb_niclist.nl_cnt == 0) {
+ smb_nic_list_destroy();
+ return (-1);
+ }
+
+ return (0);
+}
+
+static void
+smb_nic_list_destroy(void)
+{
+ free(smb_niclist.nl_nics);
+ smb_niclist.nl_nics = NULL;
+ smb_niclist.nl_cnt = 0;
+}
+
+/*
+ * smb_nic_getinfo
+ *
+ * Get IP info and more for the given interface
+ */
+static int
+smb_nic_getinfo(char *interface, smb_nic_t *nc)
+{
+ struct lifreq lifrr;
+ struct sockaddr_in *sa;
+ int s;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
+ return (-1);
+ }
+
+ (void) strlcpy(lifrr.lifr_name, interface, sizeof (lifrr.lifr_name));
+ if (ioctl(s, SIOCGLIFADDR, &lifrr) < 0) {
+ (void) close(s);
+ return (-1);
+ }
+ sa = (struct sockaddr_in *)&lifrr.lifr_addr;
+ nc->nic_ip = (uint32_t)sa->sin_addr.s_addr;
+
+ if (nc->nic_ip == 0) {
+ (void) close(s);
+ return (-1);
+ }
+
+ if (ioctl(s, SIOCGLIFBRDADDR, &lifrr) < 0) {
+ (void) close(s);
+ return (-1);
+ }
+ sa = (struct sockaddr_in *)&lifrr.lifr_broadaddr;
+ nc->nic_bcast = (uint32_t)sa->sin_addr.s_addr;
+
+ if (ioctl(s, SIOCGLIFNETMASK, &lifrr) < 0) {
+ (void) close(s);
+ return (-1);
+ }
+ sa = (struct sockaddr_in *)&lifrr.lifr_addr;
+ nc->nic_mask = (uint32_t)sa->sin_addr.s_addr;
+
+ if (ioctl(s, SIOCGLIFFLAGS, &lifrr) < 0) {
+ (void) close(s);
+ return (-1);
+ }
+ nc->nic_sysflags = lifrr.lifr_flags;
+
+ (void) strlcpy(nc->nic_ifname, interface, sizeof (nc->nic_ifname));
+
+ (void) close(s);
+ return (0);
+}
+
+/*
+ * smb_nic_hlist_create
+ *
+ * Creates a list of hosts and their associated interfaces.
+ * If host database exists the information is retrieved from
+ * the database, otherwise it's retrieved from OS.
+ *
+ * The allocated memories for the returned list should be freed
+ * by calling smb_nic_hlist_destroy()
+ */
+static int
+smb_nic_hlist_create(smb_hosts_t *hlist)
+{
+ int rc;
+
+ list_create(&hlist->h_list, sizeof (smb_hostifs_t),
+ offsetof(smb_hostifs_t, if_lnd));
+ hlist->h_num = 0;
+ hlist->h_ifnum = 0;
+
+ if (smb_nic_dbexists() && smb_nic_dbvalidate()) {
+ rc = smb_nic_hlist_dbget(hlist);
+ errno = EBADF;
+ } else {
+ rc = smb_nic_hlist_sysget(hlist);
+ }
+
+ if (rc != 0)
+ smb_nic_hlist_destroy(hlist);
+
+ return (rc);
+}
+
+static void
+smb_nic_hlist_destroy(smb_hosts_t *hlist)
+{
+ smb_hostifs_t *iflist;
+
+ if (hlist == NULL)
+ return;
+
+ while ((iflist = list_head(&hlist->h_list)) != NULL) {
+ list_remove(&hlist->h_list, iflist);
+ smb_nic_iflist_destroy(iflist);
+ }
+
+ list_destroy(&hlist->h_list);
+}
+
+/*
+ * smb_nic_hlist_sysget
+ *
+ * Get the list of currently plumbed and up interface names. The loopback (lo0)
+ * port is ignored
+ */
+static int
+smb_nic_hlist_sysget(smb_hosts_t *hlist)
+{
+ smb_hostifs_t *iflist;
+ struct ifconf ifc;
+ struct ifreq ifr;
+ struct ifreq *ifrp;
+ char *ifname;
+ int ifnum;
+ int i;
+ int s;
+
+ iflist = malloc(sizeof (smb_hostifs_t));
+ if (iflist == NULL)
+ return (-1);
+
+ bzero(iflist, sizeof (smb_hostifs_t));
+
+ if (smb_gethostname(iflist->if_host, sizeof (iflist->if_host), 0) < 0) {
+ free(iflist);
+ return (-1);
+ }
+
+ (void) smb_config_getstr(SMB_CI_SYS_CMNT, iflist->if_cmnt,
+ sizeof (iflist->if_cmnt));
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ free(iflist);
+ return (-1);
+ }
+
+ if (ioctl(s, SIOCGIFNUM, (char *)&ifnum) < 0) {
+ (void) close(s);
+ free(iflist);
+ return (-1);
+ }
+
+ ifc.ifc_len = ifnum * sizeof (struct ifreq);
+ ifc.ifc_buf = malloc(ifc.ifc_len);
+ if (ifc.ifc_buf == NULL) {
+ (void) close(s);
+ free(iflist);
+ return (-1);
+ }
+ bzero(ifc.ifc_buf, ifc.ifc_len);
+
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ (void) close(s);
+ free(iflist);
+ free(ifc.ifc_buf);
+ return (-1);
+ }
+
+ ifrp = ifc.ifc_req;
+ ifnum = ifc.ifc_len / sizeof (struct ifreq);
+
+ for (i = 0; i < ifnum; i++, ifrp++) {
+ /*
+ * Get the flags so that we can skip the loopback interface
+ */
+ (void) memset(&ifr, 0, sizeof (ifr));
+ (void) strlcpy(ifr.ifr_name, ifrp->ifr_name,
+ sizeof (ifr.ifr_name));
+
+ if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
+ (void) close(s);
+ free(ifc.ifc_buf);
+ smb_nic_iflist_destroy(iflist);
+ return (-1);
+ }
+
+ if (ifr.ifr_flags & IFF_LOOPBACK)
+ continue;
+
+ if ((ifr.ifr_flags & IFF_UP) == 0)
+ continue;
+
+ ifname = strdup(ifrp->ifr_name);
+ if (ifname == NULL) {
+ (void) close(s);
+ free(ifc.ifc_buf);
+ smb_nic_iflist_destroy(iflist);
+ return (-1);
+ }
+ iflist->if_names[iflist->if_num++] = ifname;
+ }
+
+ (void) close(s);
+ free(ifc.ifc_buf);
+
+ hlist->h_num = 1;
+ hlist->h_ifnum = iflist->if_num;
+ list_insert_tail(&hlist->h_list, iflist);
+
+ return (0);
+}
+
+static int
+smb_nic_hlist_dbget(smb_hosts_t *hlist)
+{
+ smb_hostifs_t *iflist;
+ sqlite *db;
+ sqlite_vm *vm;
+ boolean_t error = B_FALSE;
+ const char **values;
+ char *sql;
+ char *errmsg = NULL;
+ int ncol, rc;
+
+ sql = sqlite_mprintf("SELECT * FROM hosts");
+ if (sql == NULL)
+ return (-1);
+
+ db = smb_nic_dbopen(SMB_NIC_DB_ORD);
+ if (db == NULL) {
+ sqlite_freemem(sql);
+ return (-1);
+ }
+
+ rc = sqlite_compile(db, sql, NULL, &vm, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ smb_nic_dbclose(db);
+ syslog(LOG_DEBUG, "smb_nic_hlist_dbget: failed to create"
+ " VM (%s)", NULL_MSGCHK(errmsg));
+ return (-1);
+ }
+
+ do {
+ rc = sqlite_step(vm, &ncol, &values, NULL);
+ if (rc == SQLITE_ROW) {
+ if (ncol != SMB_NIC_HTBL_NCOL) {
+ error = B_TRUE;
+ break;
+ }
+
+ if ((iflist = smb_nic_iflist_decode(values)) == NULL) {
+ error = B_TRUE;
+ break;
+ }
+
+ list_insert_tail(&hlist->h_list, iflist);
+ hlist->h_num++;
+ hlist->h_ifnum += iflist->if_num;
+ }
+ } while (rc == SQLITE_ROW);
+
+ if (rc != SQLITE_DONE)
+ error = B_TRUE;
+
+ rc = sqlite_finalize(vm, &errmsg);
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "smb_nic_hlist_dbget: failed to destroy"
+ "VM (%s)", NULL_MSGCHK(errmsg));
+ error = B_TRUE;
+ }
+
+ smb_nic_dbclose(db);
+
+ return ((error) ? -1 : 0);
+}
+
+static smb_hostifs_t *
+smb_nic_iflist_decode(const char **values)
+{
+ smb_hostifs_t *iflist;
+ char *host;
+ char *cmnt;
+ char *ifnames;
+ char *lasts;
+ char *ifname;
+ int if_num = 0;
+
+ host = (char *)values[SMB_NIC_HTBL_HOST];
+ cmnt = (char *)values[SMB_NIC_HTBL_CMNT];
+ ifnames = (char *)values[SMB_NIC_HTBL_IFS];
+
+ if ((host == NULL) || (ifnames == NULL))
+ return (NULL);
+
+ iflist = malloc(sizeof (smb_hostifs_t));
+ if (iflist == NULL)
+ return (NULL);
+
+ bzero(iflist, sizeof (smb_hostifs_t));
+
+ (void) strlcpy(iflist->if_host, host, sizeof (iflist->if_host));
+ (void) strlcpy(iflist->if_cmnt, (cmnt) ? cmnt : "",
+ sizeof (iflist->if_cmnt));
+
+ if ((ifname = strtok_r(ifnames, ",", &lasts)) == NULL)
+ return (NULL);
+
+ iflist->if_names[if_num++] = strdup(ifname);
+
+ while ((ifname = strtok_r(NULL, ",", &lasts)) != NULL)
+ iflist->if_names[if_num++] = strdup(ifname);
+
+ iflist->if_num = if_num;
+
+ for (if_num = 0; if_num < iflist->if_num; if_num++) {
+ if (iflist->if_names[if_num] == NULL) {
+ smb_nic_iflist_destroy(iflist);
+ return (NULL);
+ }
+ }
+
+ return (iflist);
+}
+
+/*
+ * smb_nic_iflist_destroy
+ *
+ * Frees allocated memory for the given IF names lists.
+ */
+static void
+smb_nic_iflist_destroy(smb_hostifs_t *iflist)
+{
+ int i;
+
+ if (iflist == NULL)
+ return;
+
+ for (i = 0; i < iflist->if_num; i++)
+ free(iflist->if_names[i]);
+
+ free(iflist);
+}
+
+/*
+ * Functions to manage host/interface database
+ *
+ * Each entry in the hosts table associates a hostname with a
+ * list of interface names. The host/interface association could
+ * be added by calling smb_nic_addhost() and could be removed by
+ * calling smb_nic_delhost(). If the database exists and it contains
+ * valid information then the inteface list wouldn't be obtained
+ * from system using ioctl.
+ */
+
+/*
+ * smb_nic_dbcreate
+ *
+ * Creates the host database based on the defined SQL statement.
+ * It also initializes db_info table.
+ */
+static int
+smb_nic_dbcreate(void)
+{
+ sqlite *db = NULL;
+ char *errmsg = NULL;
+ int rc;
+
+ (void) unlink(SMB_NIC_DB_NAME);
+
+ db = sqlite_open(SMB_NIC_DB_NAME, 0600, &errmsg);
+ if (db == NULL) {
+ syslog(LOG_DEBUG, "failed to create host database (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SQLITE_CANTOPEN);
+ }
+
+ sqlite_busy_timeout(db, SMB_NIC_DB_TIMEOUT);
+ rc = sqlite_exec(db, "BEGIN TRANSACTION", NULL, NULL, &errmsg);
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to begin database transaction (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ sqlite_close(db);
+ return (rc);
+ }
+
+ if (sqlite_exec(db, SMB_NIC_DB_SQL, NULL, NULL, &errmsg) == SQLITE_OK) {
+ rc = sqlite_exec(db, "COMMIT TRANSACTION", NULL, NULL,
+ &errmsg);
+ if (rc == SQLITE_OK)
+ rc = smb_nic_dbsetinfo(db);
+ if (rc != SQLITE_OK)
+ rc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
+ &errmsg);
+ } else {
+ syslog(LOG_ERR, "failed to initialize host database (%s)",
+ errmsg);
+ sqlite_freemem(errmsg);
+ rc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
+ &errmsg);
+ }
+
+ if (rc != SQLITE_OK) {
+ /* this is bad - database may be left in a locked state */
+ syslog(LOG_DEBUG, "failed to close a transaction (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ }
+
+ (void) sqlite_close(db);
+ return (rc);
+}
+
+/*
+ * smb_nic_dbopen
+ *
+ * Opens host database with the given mode.
+ */
+static sqlite *
+smb_nic_dbopen(int mode)
+{
+ sqlite *db;
+ char *errmsg = NULL;
+
+ db = sqlite_open(SMB_NIC_DB_NAME, mode, &errmsg);
+ if (db == NULL) {
+ syslog(LOG_ERR, "failed to open group database (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ }
+
+ return (db);
+}
+
+/*
+ * smb_nic_dbclose
+ *
+ * Closes the given database handle
+ */
+static void
+smb_nic_dbclose(sqlite *db)
+{
+ if (db) {
+ sqlite_close(db);
+ }
+}
+
+static boolean_t
+smb_nic_dbexists(void)
+{
+ return (access(SMB_NIC_DB_NAME, F_OK) == 0);
+}
+
+static boolean_t
+smb_nic_dbvalidate(void)
+{
+ sqlite *db;
+ char *errmsg = NULL;
+ char *sql;
+ char **result;
+ int nrow, ncol;
+ boolean_t check = B_TRUE;
+ int rc;
+
+ sql = sqlite_mprintf("SELECT * FROM db_info");
+ if (sql == NULL)
+ return (B_FALSE);
+
+ db = smb_nic_dbopen(SMB_NIC_DB_ORW);
+ if (db == NULL) {
+ sqlite_freemem(sql);
+ return (B_FALSE);
+ }
+
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "smb_nic_dbvalidate: failed to get db_info"
+ " (%s)", NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ smb_nic_dbclose(db);
+ return (B_FALSE);
+ }
+
+ if (nrow != 1 || ncol != 3) {
+ syslog(LOG_DEBUG, "smb_nic_dbvalidate: bad db_info table");
+ sqlite_free_table(result);
+ smb_nic_dbclose(db);
+ return (B_FALSE);
+ }
+
+ if ((atoi(result[3]) != SMB_NIC_DB_VERMAJOR) ||
+ (atoi(result[4]) != SMB_NIC_DB_VERMINOR) ||
+ (atoi(result[5]) != SMB_NIC_DB_MAGIC)) {
+ syslog(LOG_DEBUG, "smb_nic_dbvalidate: bad db_info content");
+ sqlite_free_table(result);
+ smb_nic_dbclose(db);
+ return (B_FALSE);
+ }
+ sqlite_free_table(result);
+
+ sql = sqlite_mprintf("SELECT hostname FROM hosts");
+ if (sql == NULL) {
+ smb_nic_dbclose(db);
+ return (B_FALSE);
+ }
+
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "smb_nic_dbvalidate: failed to count (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ smb_nic_dbclose(db);
+ return (B_FALSE);
+ }
+
+ sqlite_free_table(result);
+
+ if (nrow == 0)
+ /* No hosts in the database */
+ check = B_FALSE;
+
+ smb_nic_dbclose(db);
+ return (check);
+}
+
+static int
+smb_nic_dbaddhost(const char *host, const char *cmnt, char *if_list)
+{
+ sqlite *db;
+ char *sql;
+ char *errmsg;
+ int rc;
+
+ sql = sqlite_mprintf("REPLACE INTO hosts (hostname, comment, ifnames)"
+ "VALUES ('%s', '%q', '%s')", host, (cmnt) ? cmnt : "", if_list);
+ if (sql == NULL)
+ return (SQLITE_NOMEM);
+
+ db = smb_nic_dbopen(SMB_NIC_DB_ORW);
+ if (db == NULL) {
+ sqlite_freemem(sql);
+ return (SQLITE_CANTOPEN);
+ }
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+ smb_nic_dbclose(db);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "smb_nic_dbaddhost: failed to insert %s (%s)",
+ host, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ }
+
+ return (rc);
+}
+
+static int
+smb_nic_dbdelhost(const char *host)
+{
+ sqlite *db;
+ char *sql;
+ char *errmsg;
+ int rc;
+
+ sql = sqlite_mprintf("DELETE FROM hosts WHERE hostname = '%s'", host);
+ if (sql == NULL)
+ return (SQLITE_NOMEM);
+
+ db = smb_nic_dbopen(SMB_NIC_DB_ORW);
+ if (db == NULL) {
+ sqlite_freemem(sql);
+ return (SQLITE_CANTOPEN);
+ }
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+ smb_nic_dbclose(db);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "smb_nic_dbdelhost: failed to delete %s (%s)",
+ host, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_nic_dbsetinfo
+ *
+ * Initializes the db_info table upon database creation.
+ */
+static int
+smb_nic_dbsetinfo(sqlite *db)
+{
+ char *errmsg = NULL;
+ char *sql;
+ int rc;
+
+ sql = sqlite_mprintf("INSERT INTO db_info (ver_major, ver_minor,"
+ " magic) VALUES (%d, %d, %d)", SMB_NIC_DB_VERMAJOR,
+ SMB_NIC_DB_VERMINOR, SMB_NIC_DB_MAGIC);
+
+ if (sql == NULL)
+ return (SQLITE_NOMEM);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "smb_nic_dbsetinfo: failed to insert database"
+ " information (%s)", NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ }
+
+ return (rc);
+}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c b/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c
index cc0cddebcd..1c9ff0707e 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c
@@ -36,12 +36,17 @@
#include <fcntl.h>
#include <thread.h>
#include <pwd.h>
+#include <dlfcn.h>
+#include <link.h>
#include <smbsrv/libsmb.h>
#define SMB_PASSWD "/var/smb/smbpasswd"
#define SMB_OPASSWD "/var/smb/osmbpasswd"
#define SMB_PASSTEMP "/var/smb/ptmp"
#define SMB_PASSLCK "/var/smb/.pwd.lock"
+#define SMB_LIBPALT "/usr/lib/smbsrv"
+#define SMB_LIBNALT "libsmb_pwd.so"
+#define SMB_LIB_ALT SMB_LIBPALT "/" SMB_LIBNALT
#define SMB_PWD_DISABLE "*DIS*"
#define SMB_PWD_BUFSIZE 256
@@ -69,12 +74,20 @@ static pid_t lck_pid = 0; /* process's pid at last lock */
static thread_t lck_tid = 0; /* thread that holds the lock */
static int fildes = -1;
static mutex_t lck_lock = DEFAULTMUTEX;
+static void *smb_pwd_hdl = NULL;
typedef struct smb_pwbuf {
char *pw_name;
smb_passwd_t *pw_pwd;
} smb_pwbuf_t;
+static struct {
+ smb_passwd_t *(*smb_pwd_getpasswd)(const char *name,
+ smb_passwd_t *smbpw);
+ int (*smb_pwd_setcntl)(const char *name, int control);
+ int (*smb_pwd_setpasswd)(const char *name, const char *password);
+} smb_pwd_ops;
+
static int smb_pwd_lock(void);
static int smb_pwd_unlock(void);
static int smb_pwd_flck(void);
@@ -85,6 +98,45 @@ static int smb_pwd_fputent(FILE *, smb_pwbuf_t *);
static int smb_pwd_chgpwent(smb_passwd_t *, const char *, int);
static int smb_pwd_update(const char *, const char *, int);
+void
+smb_pwd_init(void)
+{
+ smb_pwd_hdl = dlopen(SMB_LIB_ALT, RTLD_NOW | RTLD_LOCAL);
+
+ if (smb_pwd_hdl == NULL)
+ return; /* interposition library not found */
+
+ bzero((void *)&smb_pwd_ops, sizeof (smb_pwd_ops));
+
+ smb_pwd_ops.smb_pwd_getpasswd =
+ (smb_passwd_t *(*)())dlsym(smb_pwd_hdl, "smb_pwd_getpasswd");
+
+ smb_pwd_ops.smb_pwd_setcntl =
+ (int (*)())dlsym(smb_pwd_hdl, "smb_pwd_setcntl");
+
+ smb_pwd_ops.smb_pwd_setpasswd =
+ (int (*)())dlsym(smb_pwd_hdl, "smb_pwd_setpasswd");
+
+ if (smb_pwd_ops.smb_pwd_getpasswd == NULL ||
+ smb_pwd_ops.smb_pwd_setcntl == NULL ||
+ smb_pwd_ops.smb_pwd_setpasswd == NULL) {
+ (void) dlclose(smb_pwd_hdl);
+ smb_pwd_hdl = NULL;
+
+ /* If error or function(s) are missing, use original lib */
+ bzero((void *)&smb_pwd_ops, sizeof (smb_pwd_ops));
+ }
+}
+
+void
+smb_pwd_fini(void)
+{
+ if (smb_pwd_hdl) {
+ (void) dlclose(smb_pwd_hdl);
+ smb_pwd_hdl = NULL;
+ }
+}
+
/*
* smb_pwd_get
*
@@ -102,6 +154,9 @@ smb_pwd_getpasswd(const char *name, smb_passwd_t *smbpw)
int err;
FILE *fp;
+ if (smb_pwd_ops.smb_pwd_getpasswd != NULL)
+ return (smb_pwd_ops.smb_pwd_getpasswd(name, smbpw));
+
err = smb_pwd_lock();
if (err != SMB_PWE_SUCCESS)
return (NULL);
@@ -141,6 +196,9 @@ smb_pwd_getpasswd(const char *name, smb_passwd_t *smbpw)
int
smb_pwd_setpasswd(const char *name, const char *password)
{
+ if (smb_pwd_ops.smb_pwd_setpasswd != NULL)
+ return (smb_pwd_ops.smb_pwd_setpasswd(name, password));
+
return (smb_pwd_update(name, password, 0));
}
@@ -153,6 +211,9 @@ smb_pwd_setpasswd(const char *name, const char *password)
int
smb_pwd_setcntl(const char *name, int control)
{
+ if (smb_pwd_ops.smb_pwd_setcntl != NULL)
+ return (smb_pwd_ops.smb_pwd_setcntl(name, control));
+
if (control == 0)
return (SMB_PWE_SUCCESS);
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c b/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c
index 4460e70154..7bc94ea1de 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c
@@ -70,16 +70,17 @@ smb_smf_create_service_pgroup(smb_scfhandle_t *handle, char *pgroup)
int ret = SMBD_SMF_OK;
int err;
- if (handle == NULL) {
+ if (handle == NULL)
return (SMBD_SMF_SYSTEM_ERR);
- }
/*
* only create a handle if it doesn't exist. It is ok to exist
* since the pg handle will be set as a side effect.
*/
if (handle->scf_pg == NULL)
- handle->scf_pg = scf_pg_create(handle->scf_handle);
+ if ((handle->scf_pg =
+ scf_pg_create(handle->scf_handle)) == NULL)
+ return (SMBD_SMF_SYSTEM_ERR);
/*
* if the pgroup exists, we are done. If it doesn't, then we
@@ -584,6 +585,10 @@ smb_smf_scf_init(char *svc_name)
if (scf_handle_bind(handle->scf_handle) == 0) {
handle->scf_scope =
scf_scope_create(handle->scf_handle);
+
+ if (handle->scf_scope == NULL)
+ goto err;
+
if (scf_handle_get_local_scope(
handle->scf_handle, handle->scf_scope) != 0)
goto err;
@@ -591,6 +596,9 @@ smb_smf_scf_init(char *svc_name)
handle->scf_service =
scf_service_create(handle->scf_handle);
+ if (handle->scf_service == NULL)
+ goto err;
+
if (scf_scope_get_service(handle->scf_scope,
svc_name, handle->scf_service)
!= SCF_SUCCESS) {
@@ -598,6 +606,10 @@ smb_smf_scf_init(char *svc_name)
}
handle->scf_pg =
scf_pg_create(handle->scf_handle);
+
+ if (handle->scf_pg == NULL)
+ goto err;
+
handle->scf_state = SCH_STATE_INIT;
} else {
goto err;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_sqlite.h b/usr/src/lib/smbsrv/libsmb/common/smb_sqlite.h
new file mode 100644
index 0000000000..336a478d54
--- /dev/null
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_sqlite.h
@@ -0,0 +1,132 @@
+/*
+ * 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_SQLITE_H
+#define _SMB_SQLITE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sqlite/sqlite.h>
+
+#ifdef _LP64
+/*
+ * We cannot make 64-bit version of libsqlite because the code
+ * has some problems.
+ */
+
+/*ARGSUSED*/
+sqlite *
+sqlite_open(const char *filename, int mode, char **errmsg)
+{
+ return (NULL);
+}
+
+/*ARGSUSED*/
+void
+sqlite_close(sqlite *db)
+{
+}
+
+/*ARGSUSED*/
+char *
+sqlite_mprintf(const char *fmt, ...)
+{
+ return (NULL);
+}
+
+/*ARGSUSED*/
+void
+sqlite_freemem(void *p)
+{
+}
+
+/*ARGSUSED*/
+int
+sqlite_compile(sqlite *db, const char *zSql, const char **pzTail,
+ sqlite_vm **ppVm, char **pzErrmsg)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+void
+sqlite_free_table(char **res)
+{
+}
+
+/*ARGSUSED*/
+int
+sqlite_last_insert_rowid(sqlite *db)
+{
+ return (-1);
+}
+
+/*ARGSUSED*/
+void
+sqlite_busy_timeout(sqlite *db, int ms)
+{
+}
+
+/*ARGSUSED*/
+int
+sqlite_get_table(sqlite *db, const char *zSql, char ***pazResult, int *pnRow,
+ int *pnColumn, char **pzErrMsg)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+int
+sqlite_step(sqlite_vm *pVm, int *pN, const char ***pazValue,
+ const char ***pazColName)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+int
+sqlite_exec(sqlite *db, const char *zSql, sqlite_callback xCallback, void *pArg,
+ char **pzErrMsg)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+int
+sqlite_finalize(sqlite_vm *pVm, char **pzErrMsg)
+{
+ return (SQLITE_ERROR);
+}
+#endif /* _LP64 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SMB_SQLITE_H */
diff --git a/usr/src/lib/smbsrv/libsmbns/Makefile.com b/usr/src/lib/smbsrv/libsmbns/Makefile.com
index f4a45a3cac..16eaaeeec0 100644
--- a/usr/src/lib/smbsrv/libsmbns/Makefile.com
+++ b/usr/src/lib/smbsrv/libsmbns/Makefile.com
@@ -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"
@@ -41,8 +41,7 @@ OBJS_COMMON= \
smbns_netbios_cache.o \
smbns_netbios_datagram.o\
smbns_netbios_name.o \
- smbns_netlogon.o \
- smbns_nicconfig.o
+ smbns_netlogon.o
OBJECTS= $(OBJS_COMMON) $(OBJS_SHARED)
diff --git a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
index c9e6d62dae..d219598e2a 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
@@ -29,8 +29,6 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <ldap.h>
-#include <net/if.h>
-
#include <smbsrv/libsmb.h>
#ifdef __cplusplus
@@ -105,35 +103,10 @@ extern int smb_netbios_start(void);
extern void smb_netbios_shutdown(void);
extern void smb_netbios_name_reconfig(void);
-/* Browser Configure */
-extern void smb_browser_config(void);
-
-extern void smb_netlogon_request(int, int, char *);
+/* Browser Functions */
+extern void smb_browser_reconfig(void);
+extern void smb_browser_netlogon(char *);
-/*
- * NIC listing and config
- */
-#define SIZE_IP 17
-
-typedef struct {
- char ifname[LIFNAMSIZ];
- uint32_t ip;
- uint32_t mask;
- uint32_t broadcast;
- uint64_t flags;
- boolean_t exclude;
-} net_cfg_t;
-
-#define GATEWAY_FILE "/etc/defaultrouter"
-
-/* NIC Config functions */
-extern int smb_get_nameservers(struct in_addr *, int);
-extern void smb_nic_build_info(void);
-extern net_cfg_t *smb_nic_get_byind(int, net_cfg_t *);
-extern net_cfg_t *smb_nic_get_bysubnet(uint32_t, net_cfg_t *);
-extern net_cfg_t *smb_nic_get_byip(uint32_t, net_cfg_t *);
-extern int smb_nic_get_num(void);
-extern boolean_t smb_nic_status(char *, uint64_t);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
index 32e2423de6..3607ef138d 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
@@ -43,19 +43,12 @@ SUNWprivate {
dyndns_clear_rev_zone;
dyndns_update;
msdcs_lookup_ads;
- smb_browser_config;
- smb_get_nameservers;
+ smb_browser_netlogon;
+ smb_browser_reconfig;
smb_kinit;
smb_netbios_name_reconfig;
smb_netbios_start;
smb_netbios_shutdown;
- smb_netlogon_request;
- smb_nic_build_info;
- smb_nic_get_byind;
- smb_nic_get_byip;
- smb_nic_get_bysubnet;
- smb_nic_get_num;
- smb_nic_status;
local:
*;
};
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
index 7ab634fd4d..8a1da0cc4e 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
@@ -48,62 +48,39 @@
#define SMB_SERVER_SIGNATURE 0xaa550415
-/*
- * Macro definitions:
- */
-static char *lanman = MAILSLOT_LANMAN;
-static char *browse = MAILSLOT_BROWSE;
-
-typedef struct server_info {
- uint32_t type;
- uint32_t signature;
- char major;
- char minor;
- char hostname[NETBIOS_NAME_SZ];
- char comment[SMB_PI_MAX_COMMENT];
- char update_count;
- struct name_entry name;
-} server_info_t;
-
-#define BROWSER_NF_INVALID 0x00
-#define BROWSER_NF_VALID 0x01
-
-typedef struct browser_netinfo {
- uint32_t flags;
- int next_announce;
- int reps;
- int interval;
- server_info_t server;
- mutex_t mtx;
-} browser_netinfo_t;
-
-/*
- * Local Data Definitions:
- */
-static struct browser_netinfo smb_browser_info[SMB_PI_MAX_NETWORKS];
-
-static void smb_browser_init(void);
-
-static inline browser_netinfo_t *
-smb_browser_getnet(int net)
-{
- browser_netinfo_t *subnet;
-
- if (net < smb_nic_get_num()) {
- subnet = &smb_browser_info[net];
- (void) mutex_lock(&subnet->mtx);
- if (subnet->flags & BROWSER_NF_VALID)
- return (subnet);
- }
-
- return (0);
-}
+typedef struct smb_hostinfo {
+ list_node_t hi_lnd;
+ smb_nic_t hi_nic;
+ char hi_nbname[NETBIOS_NAME_SZ];
+ name_entry_t hi_netname;
+ uint32_t hi_nextannouce;
+ int hi_reps;
+ int hi_interval;
+ uint8_t hi_updatecnt;
+ uint32_t hi_type;
+} smb_hostinfo_t;
+
+typedef struct smb_browserinfo {
+ list_t bi_hlist;
+ int bi_hcnt;
+ rwlock_t bi_hlist_rwl;
+ boolean_t bi_changed;
+ mutex_t bi_mtx;
+} smb_browserinfo_t;
+
+static smb_browserinfo_t smb_binfo;
+
+static int smb_browser_init(void);
+static void smb_browser_infoinit(void);
+static void smb_browser_infoterm(void);
+static void smb_browser_infofree(void);
-static inline void
-smb_browser_putnet(browser_netinfo_t *netinfo)
+void
+smb_browser_reconfig(void)
{
- if (netinfo)
- (void) mutex_unlock(&netinfo->mtx);
+ (void) mutex_lock(&smb_binfo.bi_mtx);
+ smb_binfo.bi_changed = B_TRUE;
+ (void) mutex_unlock(&smb_binfo.bi_mtx);
}
/*
@@ -611,7 +588,7 @@ smb_browser_putnet(browser_netinfo_t *netinfo)
int
smb_browser_load_transact_header(unsigned char *buffer, int maxcnt,
- int data_count, int reply, char *mailbox)
+ int data_count, int reply, char *mailbox)
{
smb_msgbuf_t mb;
int mailboxlen;
@@ -661,66 +638,21 @@ smb_browser_load_transact_header(unsigned char *buffer, int maxcnt,
return (result);
}
-/*
- * smb_net_id
- *
- * Lookup for the given IP in the NICs info table.
- * If it finds a matching entry it'll return the index,
- * otherwise returns -1.
- *
- * SMB network table and SMB browser info table share
- * the same index.
- */
-int
-smb_net_id(uint32_t ipaddr)
-{
- uint32_t myaddr, mask;
- int net, smb_nc_cnt;
-
- smb_nc_cnt = smb_nic_get_num();
- for (net = 0; net < smb_nc_cnt; net++) {
- net_cfg_t cfg;
- if (smb_nic_get_byind(net, &cfg) == NULL)
- break;
- mask = cfg.mask;
- myaddr = cfg.ip;
- if ((ipaddr & mask) == (myaddr & mask))
- return (net);
- }
-
- return (-1);
-}
-
-/*
- * smb_browser_get_srvname
- *
- */
-struct name_entry *
-smb_browser_get_srvname(unsigned short netid)
-{
- if (netid < smb_nic_get_num())
- return (&(smb_browser_info[netid].server.name));
-
- return (NULL);
-}
-
static int
-smb_browser_addr_of_subnet(struct name_entry *name, int subnet,
+smb_browser_addr_of_subnet(struct name_entry *name, smb_hostinfo_t *hinfo,
struct name_entry *result)
{
uint32_t ipaddr, mask, saddr;
struct addr_entry *addr;
- int smb_nc_cnt;
- net_cfg_t cfg;
- smb_nc_cnt = smb_nic_get_num();
- if ((name == 0) || subnet >= smb_nc_cnt)
+ if (name == NULL)
return (-1);
- if (smb_nic_get_byind(subnet, &cfg) == NULL)
+ if (hinfo->hi_nic.nic_smbflags & SMB_NICF_ALIAS)
return (-1);
- ipaddr = cfg.ip;
- mask = cfg.mask;
+
+ ipaddr = hinfo->hi_nic.nic_ip;
+ mask = hinfo->hi_nic.nic_mask;
*result = *name;
addr = &name->addr_list;
@@ -741,27 +673,15 @@ smb_browser_addr_of_subnet(struct name_entry *name, int subnet,
static int
-smb_browser_bcast_addr_of_subnet(struct name_entry *name, int net,
+smb_browser_bcast_addr_of_subnet(struct name_entry *name, uint32_t bcast,
struct name_entry *result)
{
- uint32_t broadcast;
- int smb_nc_cnt;
- net_cfg_t cfg;
-
- smb_nc_cnt = smb_nic_get_num();
- if (net >= smb_nc_cnt)
- return (-1);
-
- if (name != 0 && name != result)
+ if (name != NULL && name != result)
*result = *name;
- if (smb_nic_get_byind(net, &cfg) == NULL)
- return (-1);
-
- broadcast = cfg.broadcast;
result->addr_list.sin.sin_family = AF_INET;
result->addr_list.sinlen = sizeof (result->addr_list.sin);
- result->addr_list.sin.sin_addr.s_addr = broadcast;
+ result->addr_list.sin.sin_addr.s_addr = bcast;
result->addr_list.sin.sin_port = htons(DGM_SRVC_UDP_PORT);
result->addr_list.forw = result->addr_list.back = &result->addr_list;
return (0);
@@ -839,16 +759,14 @@ smb_browser_bcast_addr_of_subnet(struct name_entry *name, int net,
* HostAnnouncement frames on this name as described above for D(1d).
*/
-void
-smb_browser_send_HostAnnouncement(int net, int32_t next_announcement,
+static void
+smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo,
+ uint32_t next_announcement, boolean_t remove,
struct addr_entry *addr, char suffix)
{
smb_msgbuf_t mb;
int offset, announce_len, data_length;
struct name_entry dest_name;
- struct name_entry server_name;
- struct browser_netinfo *subnet;
- server_info_t *server;
unsigned char *buffer;
uint32_t type;
char resource_domain[SMB_PI_MAX_DOMAIN];
@@ -857,16 +775,15 @@ smb_browser_send_HostAnnouncement(int net, int32_t next_announcement,
return;
(void) utf8_strupr(resource_domain);
- if (addr == 0) {
+ if (addr == NULL) {
/* Local master Browser */
- smb_init_name_struct(
- (unsigned char *)resource_domain, suffix,
+ smb_init_name_struct((unsigned char *)resource_domain, suffix,
0, 0, 0, 0, 0, &dest_name);
- if (smb_browser_bcast_addr_of_subnet(0, net, &dest_name) < 0)
+ if (smb_browser_bcast_addr_of_subnet(0, hinfo->hi_nic.nic_bcast,
+ &dest_name) < 0)
return;
} else {
- smb_init_name_struct(
- (unsigned char *)resource_domain, suffix,
+ smb_init_name_struct((unsigned char *)resource_domain, suffix,
0, 0, 0, 0, 0, &dest_name);
dest_name.addr_list = *addr;
dest_name.addr_list.forw = dest_name.addr_list.back =
@@ -880,22 +797,14 @@ smb_browser_send_HostAnnouncement(int net, int32_t next_announcement,
return;
}
- subnet = smb_browser_getnet(net);
- if (subnet == 0) {
- free(buffer);
- return;
- }
-
- server = &subnet->server;
-
data_length = 1 + 1 + 4 + 16 + 1 + 1 + 4 + 4 +
- strlen(server->comment) + 1;
+ strlen(hinfo->hi_nic.nic_cmnt) + 1;
- if ((offset = smb_browser_load_transact_header(buffer,
+ offset = smb_browser_load_transact_header(buffer,
MAX_DATAGRAM_LENGTH, data_length, ONE_WAY_TRANSACTION,
- browse)) < 0) {
+ MAILSLOT_BROWSE);
- smb_browser_putnet(subnet);
+ if (offset < 0) {
free(buffer);
return;
}
@@ -905,60 +814,66 @@ smb_browser_send_HostAnnouncement(int net, int32_t next_announcement,
* specifying a type of 0 just prior to shutting down, to allow it to
* quickly be removed from the list of available servers.
*/
- type = (nb_status.state & NETBIOS_SHUTTING_DOWN) ? 0 : server->type;
+ if (remove || (nb_status.state & NETBIOS_SHUTTING_DOWN))
+ type = 0;
+ else
+ type = hinfo->hi_type;
smb_msgbuf_init(&mb, buffer + offset, MAX_DATAGRAM_LENGTH - offset, 0);
+
announce_len = smb_msgbuf_encode(&mb, "bbl16cbblls",
- (char)HOST_ANNOUNCEMENT, /* Announcement opcode */
- (char)++subnet->server.update_count,
+ HOST_ANNOUNCEMENT,
+ ++hinfo->hi_updatecnt,
next_announcement * 60000, /* Periodicity in MilliSeconds */
- server->hostname, /* Server name */
- server->major, /* our major version */
- server->minor, /* our minor version */
- type, /* server type */
- server->signature, /* Signature */
- server->comment); /* Let 'em know */
-
- server_name = server->name;
- smb_browser_putnet(subnet);
+ hinfo->hi_nbname,
+ SMB_VERSION_MAJOR,
+ SMB_VERSION_MINOR,
+ type,
+ SMB_SERVER_SIGNATURE,
+ hinfo->hi_nic.nic_cmnt);
if (announce_len > 0)
- (void) smb_netbios_datagram_send(&server_name, &dest_name,
+ (void) smb_netbios_datagram_send(&hinfo->hi_netname, &dest_name,
buffer, offset + announce_len);
free(buffer);
smb_msgbuf_term(&mb);
}
-void
+static void
smb_browser_process_AnnouncementRequest(struct datagram *datagram,
char *mailbox)
{
- struct browser_netinfo *subnet;
- unsigned int next_announcement;
+ smb_hostinfo_t *hinfo;
+ uint32_t next_announcement;
uint32_t delay = random() % 29; /* in seconds */
- int net;
+ boolean_t h_found = B_FALSE;
- if (strcmp(mailbox, lanman) != 0) {
+ if (strcmp(mailbox, MAILSLOT_LANMAN) != 0) {
syslog(LOG_DEBUG, "smb_browse: Wrong Mailbox (%s)", mailbox);
return;
}
- net = smb_net_id(datagram->src.addr_list.sin.sin_addr.s_addr);
- if (net < 0) {
- /* We don't know who this is so ignore it... */
- return;
- }
-
(void) sleep(delay);
- subnet = smb_browser_getnet(net);
- if (subnet) {
- next_announcement = subnet->next_announce * 60 * 1000;
- smb_browser_putnet(subnet);
- smb_browser_send_HostAnnouncement(net, next_announcement,
- &datagram->src.addr_list, 0x1D);
+ (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
+ hinfo = list_head(&smb_binfo.bi_hlist);
+ while (hinfo) {
+ if ((hinfo->hi_nic.nic_ip & hinfo->hi_nic.nic_mask) ==
+ (datagram->src.addr_list.sin.sin_addr.s_addr &
+ hinfo->hi_nic.nic_mask)) {
+ h_found = B_TRUE;
+ break;
+ }
+ hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
+ }
+
+ if (h_found) {
+ next_announcement = hinfo->hi_nextannouce * 60 * 1000;
+ smb_browser_send_HostAnnouncement(hinfo, next_announcement,
+ B_FALSE, &datagram->src.addr_list, 0x1D);
}
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
}
void *
@@ -1119,19 +1034,20 @@ smb_browser_dispatch(void *arg)
* This name is registered by Primary Domain Controllers.
*/
-void
+static void
smb_browser_config(void)
{
+ smb_hostinfo_t *hinfo;
struct name_entry name;
struct name_entry master;
struct name_entry dest;
struct name_entry *entry;
- int smb_nc_cnt;
- net_cfg_t cfg;
- int net;
char resource_domain[SMB_PI_MAX_DOMAIN];
+ int rc;
+
+ if (smb_browser_init() != 0)
+ return;
- smb_browser_init();
if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
return;
(void) utf8_strupr(resource_domain);
@@ -1142,18 +1058,17 @@ smb_browser_config(void)
entry = smb_name_find_name(&name);
smb_name_unlock_name(entry);
- smb_nc_cnt = smb_nic_get_num();
- for (net = 0; net < smb_nc_cnt; net++) {
- if (smb_nic_get_byind(net, &cfg) == NULL)
- break;
- if (cfg.exclude)
- continue;
- smb_init_name_struct(
- (unsigned char *)resource_domain, 0x00, 0,
- cfg.ip, htons(DGM_SRVC_UDP_PORT),
+ (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
+ hinfo = list_head(&smb_binfo.bi_hlist);
+ while (hinfo) {
+ smb_init_name_struct((unsigned char *)resource_domain, 0x00, 0,
+ hinfo->hi_nic.nic_ip, htons(DGM_SRVC_UDP_PORT),
NAME_ATTR_GROUP, NAME_ATTR_LOCAL, &name);
(void) smb_name_add_name(&name);
+
+ hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
}
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
/* All our local master browsers */
smb_init_name_struct((unsigned char *)resource_domain, 0x1D,
@@ -1161,16 +1076,23 @@ smb_browser_config(void)
entry = smb_name_find_name(&dest);
if (entry) {
- for (net = 0; net < smb_nc_cnt; net++) {
- if (smb_browser_addr_of_subnet(entry, net, &master)
- == 0) {
+ (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
+ hinfo = list_head(&smb_binfo.bi_hlist);
+ while (hinfo) {
+ rc = smb_browser_addr_of_subnet(entry, hinfo, &master);
+ if (rc == 0) {
syslog(LOG_DEBUG,
"smbd: Master browser found at %s",
inet_ntoa(master.addr_list.sin.sin_addr));
}
+ hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
}
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+
smb_name_unlock_name(entry);
}
+
+ /* Domain master browser */
smb_init_name_struct((unsigned char *)resource_domain,
0x1B, 0, 0, 0, 0, 0, &dest);
@@ -1182,65 +1104,60 @@ smb_browser_config(void)
}
}
-static void
-smb_browser_init()
+static int
+smb_browser_init(void)
{
- struct browser_netinfo *subnet;
- struct server_info *server;
- char cmnt[SMB_PI_MAX_COMMENT], hostname[MAXHOSTNAMELEN];
- int i, j;
- int smb_nc_cnt;
- net_cfg_t cfg;
-
- (void) smb_gethostname(hostname, MAXHOSTNAMELEN, 1);
- (void) smb_config_getstr(SMB_CI_SYS_CMNT, cmnt, sizeof (cmnt));
-
- smb_nc_cnt = smb_nic_get_num();
- for (i = 0; i < smb_nc_cnt; i++) {
- if (smb_nic_get_byind(i, &cfg) == NULL)
- break;
- if (cfg.exclude)
- continue;
+ smb_hostinfo_t *hinfo;
+ smb_niciter_t ni;
+ uint32_t type;
- subnet = &smb_browser_info[i];
- (void) mutex_lock(&subnet->mtx);
+ (void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
+ smb_browser_infofree();
- /* One Minute announcements for first five */
- subnet->flags = BROWSER_NF_VALID;
- subnet->next_announce = 1;
- subnet->interval = 1;
- subnet->reps = 5;
-
- server = &subnet->server;
- bzero(server, sizeof (struct server_info));
-
- server->type = MY_SERVER_TYPE;
- server->major = SMB_VERSION_MAJOR;
- server->minor = SMB_VERSION_MINOR;
- server->signature = SMB_SERVER_SIGNATURE;
- (void) strlcpy(server->comment, cmnt, SMB_PI_MAX_COMMENT);
-
- (void) snprintf(server->hostname, NETBIOS_NAME_SZ, "%.15s",
- hostname);
-
- /*
- * 00 is workstation service.
- * 20 is file server service.
- */
- smb_init_name_struct((unsigned char *)server->hostname, 0x20, 0,
- cfg.ip, htons(DGM_SRVC_UDP_PORT),
- NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &server->name);
-
- (void) mutex_unlock(&subnet->mtx);
+ if (smb_nic_getfirst(&ni) != 0) {
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+ return (-1);
}
- /* Invalidate unconfigured NICs */
- for (j = i; j < SMB_PI_MAX_NETWORKS; j++) {
- subnet = &smb_browser_info[j];
- (void) mutex_lock(&subnet->mtx);
- subnet->flags = BROWSER_NF_INVALID;
- (void) mutex_unlock(&subnet->mtx);
- }
+ type = MY_SERVER_TYPE;
+ if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN)
+ type |= SV_DOMAIN_MEMBER;
+
+ do {
+ if (ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL)
+ continue;
+
+ hinfo = malloc(sizeof (smb_hostinfo_t));
+ if (hinfo == NULL) {
+ smb_browser_infofree();
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+ return (-1);
+ }
+
+ hinfo->hi_nic = ni.ni_nic;
+ /* One Minute announcements for first five */
+ hinfo->hi_nextannouce = 1;
+ hinfo->hi_interval = 1;
+ hinfo->hi_reps = 5;
+ hinfo->hi_updatecnt = 0;
+ hinfo->hi_type = type;
+
+ /* This is the name used for HostAnnouncement */
+ (void) strlcpy(hinfo->hi_nbname, hinfo->hi_nic.nic_host,
+ NETBIOS_NAME_SZ);
+ (void) utf8_strupr(hinfo->hi_nbname);
+
+ /* 0x20: file server service */
+ smb_init_name_struct((unsigned char *)hinfo->hi_nbname,
+ 0x20, 0, hinfo->hi_nic.nic_ip, htons(DGM_SRVC_UDP_PORT),
+ NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &hinfo->hi_netname);
+
+ list_insert_tail(&smb_binfo.bi_hlist, hinfo);
+ smb_binfo.bi_hcnt++;
+ } while (smb_nic_getnext(&ni) == 0);
+
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+ return (0);
}
/*
@@ -1251,24 +1168,16 @@ smb_browser_init()
* is a member of domain "D", this frame is sent to the NETBIOS unique name
* D(1d) and mailslot "\\MAILSLOT\\BROWSE".
*/
-void
-smb_browser_non_master_duties(int net)
+static void
+smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove)
{
- struct browser_netinfo *subnet;
struct name_entry name;
struct name_entry *dest;
struct addr_entry addr;
- int interval;
char resource_domain[SMB_PI_MAX_DOMAIN];
- subnet = smb_browser_getnet(net);
- if (subnet == 0)
- return;
-
- interval = subnet->interval;
- smb_browser_putnet(subnet);
-
- smb_browser_send_HostAnnouncement(net, interval, 0, 0x1D);
+ smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
+ remove, 0, 0x1D);
if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
return;
@@ -1281,41 +1190,39 @@ smb_browser_non_master_duties(int net)
addr = dest->addr_list;
addr.forw = addr.back = &addr;
smb_name_unlock_name(dest);
- smb_browser_send_HostAnnouncement(net, interval, &addr, 0x1D);
+ smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
+ remove, &addr, 0x1D);
} else {
- smb_init_name_struct(
- (unsigned char *)resource_domain, 0x1B,
+ smb_init_name_struct((unsigned char *)resource_domain, 0x1B,
0, 0, 0, 0, 0, &name);
if ((dest = smb_name_find_name(&name))) {
addr = dest->addr_list;
addr.forw = addr.back = &addr;
smb_name_unlock_name(dest);
- smb_browser_send_HostAnnouncement(net, interval,
- &addr, 0x1B);
+ smb_browser_send_HostAnnouncement(hinfo,
+ remove, hinfo->hi_interval, &addr, 0x1B);
}
}
- subnet = smb_browser_getnet(net);
/*
* One Minute announcements for first five
- * minutes, one munute longer each round
+ * minutes, one minute longer each round
* until 12 minutes and every 12 minutes
* thereafter.
*/
- if (--subnet->reps == 0) {
- if (subnet->interval < 12)
- subnet->interval++;
+ if (--hinfo->hi_reps == 0) {
+ if (hinfo->hi_interval < 12)
+ hinfo->hi_interval++;
- subnet->reps = 1;
+ hinfo->hi_reps = 1;
}
- subnet->next_announce = subnet->interval;
- smb_browser_putnet(subnet);
+ hinfo->hi_nextannouce = hinfo->hi_interval;
}
/*
- * browser_sleep
+ * smb_browser_sleep
*
* Put browser in 1 minute sleep if netbios services are not
* shutting down and both name and datagram services are still
@@ -1324,10 +1231,10 @@ smb_browser_non_master_duties(int net)
* 1 if everything is ok or 0 if browser shouldn't continue
* running.
*/
-static int
-browser_sleep()
+static boolean_t
+smb_browser_sleep(void)
{
- int slept = 0;
+ boolean_t slept = B_FALSE;
timestruc_t to;
(void) mutex_lock(&nb_status.mtx);
@@ -1337,21 +1244,21 @@ browser_sleep()
if (slept) {
(void) mutex_unlock(&nb_status.mtx);
- return (1);
+ return (B_TRUE);
}
to.tv_sec = 60; /* 1 minute */
to.tv_nsec = 0;
(void) cond_reltimedwait(&nb_status.cv, &nb_status.mtx, &to);
- slept = 1;
+ slept = B_TRUE;
}
(void) mutex_unlock(&nb_status.mtx);
- return (0);
+ return (B_FALSE);
}
/*
- * smb_browser_start
+ * smb_browser_daemon
*
* Smb Netbios browser daemon.
*/
@@ -1359,38 +1266,125 @@ browser_sleep()
void *
smb_browser_daemon(void *arg)
{
- int net;
- int next_announce;
- struct browser_netinfo *subnet;
- int run = 1;
- int smb_nc_cnt;
- net_cfg_t cfg;
+ smb_hostinfo_t *hinfo;
+ smb_browser_infoinit();
smb_browser_config();
- nb_status.state |= NETBIOS_BROWSER_RUNNING;
+ smb_netbios_chg_status(NETBIOS_BROWSER_RUNNING, 1);
- while (run) {
- smb_nc_cnt = smb_nic_get_num();
- for (net = 0; net < smb_nc_cnt; net++) {
- if (smb_nic_get_byind(net, &cfg) == NULL)
- break;
- if (cfg.exclude)
+restart:
+ do {
+ (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
+ hinfo = list_head(&smb_binfo.bi_hlist);
+ while (hinfo) {
+ if (--hinfo->hi_nextannouce > 0 ||
+ hinfo->hi_nic.nic_bcast == 0) {
+ hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
continue;
+ }
- subnet = smb_browser_getnet(net);
- next_announce = --subnet->next_announce;
- smb_browser_putnet(subnet);
+ smb_browser_non_master_duties(hinfo, B_FALSE);
- if (next_announce > 0 || cfg.broadcast == 0)
- continue;
+ /* Check to see whether reconfig is needed */
+ (void) mutex_lock(&smb_binfo.bi_mtx);
+ if (smb_binfo.bi_changed) {
+ smb_binfo.bi_changed = B_FALSE;
+ (void) mutex_unlock(&smb_binfo.bi_mtx);
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+ smb_browser_config();
+ goto restart;
+ }
+ (void) mutex_unlock(&smb_binfo.bi_mtx);
- smb_browser_non_master_duties(net);
+ hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
}
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+ } while (smb_browser_sleep());
- run = browser_sleep();
- }
-
+ smb_browser_infoterm();
smb_netbios_chg_status(NETBIOS_BROWSER_RUNNING, 0);
return (0);
}
+
+/*
+ * smb_browser_netlogon
+ *
+ * Sends SAMLOGON/NETLOGON request for all host/ips, except
+ * aliases, to find a domain controller.
+ */
+void
+smb_browser_netlogon(char *domain)
+{
+ smb_hostinfo_t *hinfo;
+ int protocol;
+
+ if (smb_config_getbool(SMB_CI_DOMAIN_MEMB))
+ protocol = NETLOGON_PROTO_SAMLOGON;
+ else
+ protocol = NETLOGON_PROTO_NETLOGON;
+
+ (void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
+ hinfo = list_head(&smb_binfo.bi_hlist);
+ while (hinfo) {
+ if ((hinfo->hi_nic.nic_smbflags & SMB_NICF_ALIAS) == 0)
+ smb_netlogon_request(&hinfo->hi_netname, protocol,
+ domain);
+ hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
+ }
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+}
+
+/*
+ * smb_browser_infoinit
+ *
+ * This function is called only once when browser daemon starts
+ * to initialize global smb_binfo structure
+ */
+static void
+smb_browser_infoinit(void)
+{
+ (void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
+ list_create(&smb_binfo.bi_hlist, sizeof (smb_hostinfo_t),
+ offsetof(smb_hostinfo_t, hi_lnd));
+ smb_binfo.bi_hcnt = 0;
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+
+ (void) mutex_lock(&smb_binfo.bi_mtx);
+ smb_binfo.bi_changed = B_FALSE;
+ (void) mutex_unlock(&smb_binfo.bi_mtx);
+}
+
+/*
+ * smb_browser_infoterm
+ *
+ * This function is called only once when browser daemon stops
+ * to destruct smb_binfo structure
+ */
+static void
+smb_browser_infoterm(void)
+{
+ (void) rw_wrlock(&smb_binfo.bi_hlist_rwl);
+ smb_browser_infofree();
+ list_destroy(&smb_binfo.bi_hlist);
+ (void) rw_unlock(&smb_binfo.bi_hlist_rwl);
+}
+
+/*
+ * smb_browser_infofree
+ *
+ * Removes all the hostinfo structures from the browser list
+ * and frees the allocated memory
+ */
+static void
+smb_browser_infofree(void)
+{
+ smb_hostinfo_t *hinfo;
+
+ while ((hinfo = list_head(&smb_binfo.bi_hlist)) != NULL) {
+ list_remove(&smb_binfo.bi_hlist, hinfo);
+ free(hinfo);
+ }
+
+ smb_binfo.bi_hcnt = 0;
+}
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
index 8d96268c0a..46d1c5e47e 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
@@ -1671,11 +1671,11 @@ dyndns_remove_entry(int update_zone, const char *hostname, const char *ip_addr,
int
dyndns_update(void)
{
- int i, forw_update_ok, error;
+ int forw_update_ok, error;
char fqdn[MAXHOSTNAMELEN];
char *my_ip;
- int nc_cnt;
struct in_addr addr;
+ smb_niciter_t ni;
int rc;
if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
@@ -1684,8 +1684,6 @@ dyndns_update(void)
if (smb_getfqhostname(fqdn, MAXHOSTNAMELEN) != 0)
return (-1);
- nc_cnt = smb_nic_get_num();
-
error = 0;
forw_update_ok = 0;
@@ -1698,17 +1696,14 @@ dyndns_update(void)
error++;
}
- for (i = 0; i < nc_cnt; i++) {
- net_cfg_t cfg;
- if (smb_nic_get_byind(i, &cfg) == NULL)
- break;
- addr.s_addr = cfg.ip;
- if (addr.s_addr == 0)
- continue;
- if (smb_nic_status(cfg.ifname, IFF_STANDBY) ||
- smb_nic_status(cfg.ifname, IFF_PRIVATE))
+ if (smb_nic_getfirst(&ni) != 0)
+ return (-1);
+
+ do {
+ if (ni.ni_nic.nic_sysflags & (IFF_STANDBY | IFF_PRIVATE))
continue;
+ addr.s_addr = ni.ni_nic.nic_ip;
my_ip = (char *)strdup(inet_ntoa(addr));
if (my_ip == NULL) {
error++;
@@ -1733,7 +1728,7 @@ dyndns_update(void)
error++;
(void) free(my_ip);
- }
+ } while (smb_nic_getnext(&ni) == 0);
return ((error == 0) ? 0 : -1);
}
@@ -1752,11 +1747,11 @@ dyndns_update(void)
int
dyndns_clear_rev_zone(void)
{
- int i, error;
+ int error;
char fqdn[MAXHOSTNAMELEN];
char *my_ip;
- int nc_cnt;
struct in_addr addr;
+ smb_niciter_t ni;
int rc;
if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
@@ -1765,21 +1760,16 @@ dyndns_clear_rev_zone(void)
if (smb_getfqhostname(fqdn, MAXHOSTNAMELEN) != 0)
return (-1);
- nc_cnt = smb_nic_get_num();
-
error = 0;
- for (i = 0; i < nc_cnt; i++) {
- net_cfg_t cfg;
- if (smb_nic_get_byind(i, &cfg) == NULL)
- break;
- addr.s_addr = cfg.ip;
- if (addr.s_addr == 0)
- continue;
- if (smb_nic_status(cfg.ifname, IFF_STANDBY) ||
- smb_nic_status(cfg.ifname, IFF_PRIVATE))
+ if (smb_nic_getfirst(&ni) != 0)
+ return (-1);
+
+ do {
+ if (ni.ni_nic.nic_sysflags & (IFF_STANDBY | IFF_PRIVATE))
continue;
+ addr.s_addr = ni.ni_nic.nic_ip;
my_ip = (char *)strdup(inet_ntoa(addr));
if (my_ip == NULL) {
error++;
@@ -1791,7 +1781,7 @@ dyndns_clear_rev_zone(void)
error++;
(void) free(my_ip);
- }
+ } while (smb_nic_getnext(&ni) == 0);
return ((error == 0) ? 0 : -1);
}
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
index 4f8340dcca..0f9380c114 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
@@ -159,27 +159,26 @@ smb_netbios_start(void)
static void *
smb_netbios_timer(void *arg)
{
- static unsigned int ticks;
+ static unsigned int ticks = 0;
smb_netbios_chg_status(NETBIOS_TIMER_RUNNING, 1);
while ((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) {
(void) sleep(1);
+ ticks++;
- if (nb_status.state & NETBIOS_DATAGRAM_SVC_RUNNING)
- smb_netbios_datagram_tick();
- else
+ if ((nb_status.state & NETBIOS_DATAGRAM_SVC_RUNNING) == 0)
break;
- if (nb_status.state & NETBIOS_NAME_SVC_RUNNING) {
- smb_netbios_name_tick();
-
- /* every 10 minutes */
- if ((ticks % 600) == 0)
- smb_netbios_cache_clean();
- }
- else
+ if ((nb_status.state & NETBIOS_NAME_SVC_RUNNING) == 0)
break;
+
+ smb_netbios_datagram_tick();
+ smb_netbios_name_tick();
+
+ /* every 10 minutes */
+ if ((ticks % 600) == 0)
+ smb_netbios_cache_clean();
}
nb_status.state &= ~NETBIOS_TIMER_RUNNING;
@@ -218,37 +217,16 @@ void
smb_encode_netbios_name(unsigned char *name, char suffix, unsigned char *scope,
struct name_entry *dest)
{
- char tmp_name[NETBIOS_NAME_SZ];
- mts_wchar_t wtmp_name[NETBIOS_NAME_SZ];
- unsigned int cpid;
- int len;
- size_t rc;
-
- len = 0;
- rc = mts_mbstowcs(wtmp_name, (const char *)name, NETBIOS_NAME_SZ);
-
- if (rc != (size_t)-1) {
- wtmp_name[NETBIOS_NAME_SZ - 1] = 0;
- cpid = oem_get_smb_cpid();
- rc = unicodestooems(tmp_name, wtmp_name, NETBIOS_NAME_SZ, cpid);
- if (rc > 0)
- len = strlen(tmp_name);
- }
-
- (void) memset(dest->name, ' ', NETBIOS_NAME_SZ - 1);
- if (len) {
- (void) utf8_strupr(tmp_name);
- (void) memcpy(dest->name, tmp_name, len);
- }
- dest->name[NETBIOS_NAME_SZ - 1] = suffix;
+ smb_tonetbiosname((char *)name, (char *)dest->name, suffix);
- if (scope == NULL) {
- (void) smb_config_getstr(SMB_CI_NBSCOPE, (char *)dest->scope,
- NETBIOS_DOMAIN_NAME_MAX);
- } else {
+ if (scope) {
(void) strlcpy((char *)dest->scope, (const char *)scope,
- NETBIOS_DOMAIN_NAME_MAX);
+ sizeof (dest->scope));
+ } else {
+ (void) smb_config_getstr(SMB_CI_NBSCOPE, (char *)dest->scope,
+ sizeof (dest->scope));
}
+
(void) utf8_strupr((char *)dest->scope);
}
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h
index 54ac5cf2ab..6c91115fa3 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h
@@ -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.
*/
@@ -28,928 +28,6 @@
#pragma ident "%Z%%M% %I% %E% SMI"
-/*
- * 4.2. NAME SERVICE PACKETS
- *
- * 4.2.1. GENERAL FORMAT OF NAME SERVICE PACKETS
- *
- * The NetBIOS Name Service packets follow the packet structure defined
- * in the Domain Name Service (DNS) RFC 883 [7 (pg 26-31)]. The
- * structures are compatible with the existing DNS packet formats,
- * however, additional types and codes have been added to work with
- * NetBIOS.
- *
- * If Name Service packets are sent over a TCP connection they are
- * preceded by a 16 bit unsigned integer representing the length of the
- * Name Service packet.
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * + ------ ------- +
- * | HEADER |
- * + ------ ------- +
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION ENTRIES /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / ANSWER RESOURCE RECORDS /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / AUTHORITY RESOURCE RECORDS /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / ADDITIONAL RESOURCE RECORDS /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.1.1 HEADER
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID | OPCODE | NM_FLAGS | RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | QDCOUNT | ANCOUNT |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NSCOUNT | ARCOUNT |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Field Description
- *
- * NAME_TRN_ID Transaction ID for Name Service Transaction.
- * Requester places a unique value for each active
- * transaction. Responder puts NAME_TRN_ID value
- * from request packet in response packet.
- *
- * OPCODE Packet type code, see table below.
- *
- * NM_FLAGS Flags for operation, see table below.
- *
- * RCODE Result codes of request. Table of RCODE values
- * for each response packet below.
- *
- * QDCOUNT Unsigned 16 bit integer specifying the number of
- * entries in the question section of a Name
- * Service packet. Always zero (0) for responses.
- * Must be non-zero for all NetBIOS Name requests.
- *
- * ANCOUNT Unsigned 16 bit integer specifying the number of
- * resource records in the answer section of a Name
- * Service packet.
- *
- * NSCOUNT Unsigned 16 bit integer specifying the number of
- * resource records in the authority section of a
- * Name Service packet.
- *
- * ARCOUNT Unsigned 16 bit integer specifying the number of
- * resource records in the additional records
- * section of a Name Service packet.
- */
-
-
-/*
- * The OPCODE field is defined as:
- *
- * 0 1 2 3 4
- * +---+---+---+---+---+
- * | R | OPCODE |
- * +---+---+---+---+---+
- *
- * Symbol Bit(s) Description
- *
- * OPCODE 1-4 Operation specifier:
- * 0 = query
- * 5 = registration
- * 6 = release
- * 7 = WACK
- * 8 = refresh
- *
- * R 0 RESPONSE flag:
- * if bit == 0 then request packet
- * if bit == 1 then response packet.
- */
-
-/*
- * The NM_FLAGS field is defined as:
- *
- *
- * 0 1 2 3 4 5 6
- * +---+---+---+---+---+---+---+
- * |AA |TC |RD |RA | 0 | 0 | B |
- * +---+---+---+---+---+---+---+
- *
- * Symbol Bit(s) Description
- *
- * B 6 Broadcast Flag.
- * = 1: packet was broadcast or multicast
- * = 0: unicast
- *
- * RA 3 Recursion Available Flag.
- *
- * Only valid in responses from a NetBIOS Name
- * Server -- must be zero in all other
- * responses.
- *
- * If one (1) then the NBNS supports recursive
- * query, registration, and release.
- *
- * If zero (0) then the end-node must iterate
- * for query and challenge for registration.
- *
- * RD 2 Recursion Desired Flag.
- *
- * May only be set on a request to a NetBIOS
- * Name Server.
- *
- * The NBNS will copy its state into the
- * response packet.
- *
- * If one (1) the NBNS will iterate on the
- * query, registration, or release.
- *
- * TC 1 Truncation Flag.
- *
- * Set if this message was truncated because the
- * datagram carrying it would be greater than
- * 576 bytes in length. Use TCP to get the
- * information from the NetBIOS Name Server.
- *
- * AA 0 Authoritative Answer flag.
- *
- * Must be zero (0) if R flag of OPCODE is zero
- * (0).
- *
- * If R flag is one (1) then if AA is one (1)
- * then the node responding is an authority for
- * the domain name.
- *
- * End nodes responding to queries always set
- * this bit in responses.
- */
-
-/*
- * 4.2.1.2 QUESTION SECTION
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | QUESTION_TYPE | QUESTION_CLASS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Field Description
- *
- * QUESTION_NAME The compressed name representation of the
- * NetBIOS name for the request.
- *
- * QUESTION_TYPE The type of request. The values for this field
- * are specified for each request.
- *
- * QUESTION_CLASS The class of the request. The values for this
- * field are specified for each request.
- *
- * QUESTION_TYPE is defined as:
- *
- * Symbol Value Description:
- *
- * NB 0x0020 NetBIOS general Name Service Resource Record
- * NBSTAT 0x0021 NetBIOS NODE STATUS Resource Record (See NODE
- * STATUS REQUEST)
- *
- * QUESTION_CLASS is defined as:
- *
- * Symbol Value Description:
- *
- * IN 0x0001 Internet class
- */
-
-/*
- * 4.2.1.3 RESOURCE RECORD
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RR_TYPE | RR_CLASS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RDLENGTH | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- * / /
- * / RDATA /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Field Description
- *
- * RR_NAME The compressed name representation of the
- * NetBIOS name corresponding to this resource
- * record.
- *
- * RR_TYPE Resource record type code
- *
- * RR_CLASS Resource record class code
- *
- * TTL The Time To Live of a the resource record's
- * name.
- *
- * RDLENGTH Unsigned 16 bit integer that specifies the
- * number of bytes in the RDATA field.
- *
- * RDATA RR_CLASS and RR_TYPE dependent field. Contains
- * the resource information for the NetBIOS name.
- *
- * RESOURCE RECORD RR_TYPE field definitions:
- *
- * Symbol Value Description:
- *
- * A 0x0001 IP address Resource Record (See REDIRECT NAME
- * QUERY RESPONSE)
- * NS 0x0002 Name Server Resource Record (See REDIRECT
- * NAME QUERY RESPONSE)
- * NULL 0x000A NULL Resource Record (See WAIT FOR
- * ACKNOWLEDGEMENT RESPONSE)
- * NB 0x0020 NetBIOS general Name Service Resource Record
- * (See NB_FLAGS and NB_ADDRESS, below)
- * NBSTAT 0x0021 NetBIOS NODE STATUS Resource Record (See NODE
- * STATUS RESPONSE)
- *
- * RESOURCE RECORD RR_CLASS field definitions:
- *
- * Symbol Value Description:
- *
- * IN 0x0001 Internet class
- *
- * NB_FLAGS field of the RESOURCE RECORD RDATA field for RR_TYPE of
- * "NB":
- *
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | G | ONT | RESERVED |
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- *
- * Symbol Bit(s) Description:
- *
- * RESERVED 3-15 Reserved for future use. Must be zero (0).
- * ONT 1,2 Owner Node Type:
- * 00 = B node
- * 01 = P node
- * 10 = M node
- * 11 = Reserved for future use
- * For registration requests this is the
- * claimant's type.
- * For responses this is the actual owner's
- * type.
- *
- * G 0 Group Name Flag.
- * If one (1) then the RR_NAME is a GROUP
- * NetBIOS name.
- * If zero (0) then the RR_NAME is a UNIQUE
- * NetBIOS name.
- *
- * The NB_ADDRESS field of the RESOURCE RECORD RDATA field for
- * RR_TYPE of "NB" is the IP address of the name's owner.
- */
-
-/*
- * 4.2.2. NAME REGISTRATION REQUEST
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x5 |0|0|1|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Since the RR_NAME is the same name as the QUESTION_NAME, the
- * RR_NAME representation must use pointers to the QUESTION_NAME
- * name's labels to guarantee the length of the datagram is less
- * than the maximum 576 bytes. See section above on name formats
- * and also page 31 and 32 of RFC 883, Domain Names - Implementation
- * and Specification, for a complete description of compressed name
- * label pointers.
- */
-
-/*
- * 4.2.3 NAME OVERWRITE REQUEST & DEMAND
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x5 |0|0|0|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.4 NAME REFRESH REQUEST
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x9 |0|0|0|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.5 POSITIVE NAME REGISTRATION RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.6 NEGATIVE NAME REGISTRATION RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * RCODE field values:
- *
- * Symbol Value Description:
- *
- * FMT_ERR 0x1 Format Error. Request was invalidly
- * formatted.
- * SRV_ERR 0x2 Server failure. Problem with NBNS, cannot
- * process name.
- * IMP_ERR 0x4 Unsupported request error. Allowable only
- * for challenging NBNS when gets an Update type
- * registration request.
- * RFS_ERR 0x5 Refused error. For policy reasons server
- * will not register this name from this host.
- * ACT_ERR 0x6 Active error. Name is owned by another node.
- * CFT_ERR 0x7 Name in conflict error. A UNIQUE name is
- * owned by more than one node.
- */
-
-/*
- * 4.2.7 END-NODE CHALLENGE REGISTRATION RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x5 |1|0|1|0|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.8 NAME CONFLICT DEMAND
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| 0x7 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 |0|ONT|0| 0x000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * This packet is identical to a NEGATIVE NAME REGISTRATION RESPONSE
- * with RCODE = CFT_ERR.
- */
-
-/*
- * 4.2.9 NAME RELEASE REQUEST & DEMAND
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x6 |0|0|0|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Since the RR_NAME is the same name as the QUESTION_NAME, the
- * RR_NAME representation must use label string pointers to the
- * QUESTION_NAME labels to guarantee the length of the datagram is
- * less than the maximum 576 bytes. This is the same condition as
- * with the NAME REGISTRATION REQUEST.
- */
-
-/*
- * 4.2.10 POSITIVE NAME RELEASE RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x6 |1|0|0|0|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.11 NEGATIVE NAME RELEASE RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x6 |1|0|0|0|0 0|0| RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * RCODE field values:
- *
- * Symbol Value Description:
- *
- * FMT_ERR 0x1 Format Error. Request was invalidly
- * formatted.
- *
- * SRV_ERR 0x2 Server failure. Problem with NBNS, cannot
- * process name.
- *
- * RFS_ERR 0x5 Refused error. For policy reasons server
- * will not release this name from this host.
- *
- * ACT_ERR 0x6 Active error. Name is owned by another node.
- * Only that node may release it. A NetBIOS
- * Name Server can optionally allow a node to
- * release a name it does not own. This would
- * facilitate detection of inactive names for
- * nodes that went down silently.
- */
-
-/*
- * 4.2.12 NAME QUERY REQUEST
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x0 |0|0|1|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.13 POSITIVE NAME QUERY RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x0 |1|T|1|?|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RDLENGTH | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- * | |
- * / ADDR_ENTRY ARRAY /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * The ADDR_ENTRY ARRAY a sequence of zero or more ADDR_ENTRY
- * records. Each ADDR_ENTRY record represents an owner of a name.
- * For group names there may be multiple entries. However, the list
- * may be incomplete due to packet size limitations. Bit 22, "T",
- * will be set to indicate truncated data.
- *
- * Each ADDR_ENTRY has the following format:
- *
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_FLAGS | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS (continued) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.14 NEGATIVE NAME QUERY RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x0 |1|0|1|?|0 0|0| RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NULL (0x000A) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * RCODE field values:
- *
- * Symbol Value Description
- *
- * FMT_ERR 0x1 Format Error. Request was invalidly
- * formatted.
- * SRV_ERR 0x2 Server failure. Problem with NBNS, cannot
- * process name.
- * NAM_ERR 0x3 Name Error. The name requested does not
- * exist.
- * IMP_ERR 0x4 Unsupported request error. Allowable only
- * for challenging NBNS when gets an Update type
- * registration request.
- * RFS_ERR 0x5 Refused error. For policy reasons server
- * will not register this name from this host.
- */
-
-/*
- * 4.2.15 REDIRECT NAME QUERY RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x0 |0|0|1|0|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NS (0x0002) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RDLENGTH | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
- * | |
- * / NSD_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | A (0x0001) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0004 | NSD_IP_ADDR |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NSD_IP_ADDR, continued |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * An end node responding to a NAME QUERY REQUEST always responds
- * with the AA and RA bits set for both the NEGATIVE and POSITIVE
- * NAME QUERY RESPONSE packets. An end node never sends a REDIRECT
- * NAME QUERY RESPONSE packet.
- *
- * When the requestor receives the REDIRECT NAME QUERY RESPONSE it
- * must reiterate the NAME QUERY REQUEST to the NBNS specified by
- * the NSD_IP_ADDR field of the A type RESOURCE RECORD in the
- * ADDITIONAL section of the response packet. This is an optional
- * packet for the NBNS.
- *
- * The NSD_NAME and the RR_NAME in the ADDITIONAL section of the
- * response packet are the same name. Space can be optimized if
- * label string pointers are used in the RR_NAME which point to the
- * labels in the NSD_NAME.
- *
- * The RR_NAME in the AUTHORITY section is the name of the domain
- * the NBNS called by NSD_NAME has authority over.
- */
-
-/*
- * 4.2.16 WAIT FOR ACKNOWLEDGEMENT (WACK) RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x7 |1|0|0|0|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NULL (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0002 | OPCODE | NM_FLAGS | 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * The NAME_TRN_ID of the WACK RESPONSE packet is the same
- * NAME_TRN_ID of the request that the NBNS is telling the requestor
- * to wait longer to complete. The RR_NAME is the name from the
- * request, if any. If no name is available from the request then
- * it is a null name, single byte of zero.
- *
- * The TTL field of the ResourceRecord is the new time to wait, in
- * seconds, for the request to complete. The RDATA field contains
- * the OPCODE and NM_FLAGS of the request.
- *
- * A TTL value of 0 means that the NBNS can not estimate the time it
- * may take to complete a response.
- */
-
-/*
- * 4.2.17 NODE STATUS REQUEST
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x0 |0|0|0|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NBSTAT (0x0021) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/*
- * 4.2.18 NODE STATUS RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x0 |1|0|0|0|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NBSTAT (0x0021) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RDLENGTH | NUM_NAMES | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
- * | |
- * + +
- * / NODE_NAME ARRAY /
- * + +
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * + +
- * / STATISTICS /
- * + +
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
- * of NODE_NAME records. Each NODE_NAME entry represents an active
- * name in the same NetBIOS scope as the requesting name in the
- * local name table of the responder. RR_NAME is the requesting
- * name.
- */
-
#include <stdio.h>
#include <synch.h>
#include <pthread.h>
@@ -963,14 +41,14 @@
#define QUEUE_INSERT_TAIL(q, e) \
((e)->back) = (void *)((q)->back); \
- ((e)->forw) = (void *)(q); \
+ ((e)->forw) = (void *)(q); \
((q)->back->forw) = (void *)(e); \
((q)->back) = (void *)(e);
#define QUEUE_CLIP(e) \
(e)->forw->back = (e)->back; \
(e)->back->forw = (e)->forw; \
- (e)->forw = 0; \
+ (e)->forw = 0; \
(e)->back = 0;
#define NETBIOS_NAME_SVC_LAUNCHED 0x00001
@@ -994,6 +72,11 @@
char smb_node_type;
+#define SMB_NODETYPE_B 'B'
+#define SMB_NODETYPE_P 'P'
+#define SMB_NODETYPE_M 'M'
+#define SMB_NODETYPE_H 'H'
+
typedef struct {
mutex_t mtx;
cond_t cv;
@@ -1082,7 +165,7 @@ typedef struct name_entry {
unsigned short attributes;
struct addr_entry addr_list;
mutex_t mtx;
-} name_entry;
+} name_entry_t;
struct name_question {
struct name_entry *name;
@@ -1523,6 +606,11 @@ typedef struct name_queue {
mutex_t mtx;
} name_queue_t;
+typedef struct nbcache_iter {
+ HT_ITERATOR nbc_hti;
+ struct name_entry *nbc_entry;
+} nbcache_iter_t;
+
#define NETBIOS_EMPTY_NAME (unsigned char *)""
#define NETBIOS_NAME_IS_STAR(name) \
@@ -1536,13 +624,11 @@ void smb_netbios_chg_status(uint32_t status, int set);
int smb_netbios_cache_init(void);
void smb_netbios_cache_fini(void);
void smb_netbios_cache_dump(void);
-void smb_netbios_cache_print(void);
-void smb_netbios_cache_diag(char ** pbuf);
int smb_netbios_cache_count(void);
void smb_netbios_cache_clean(void);
void smb_netbios_cache_reset_ttl(void);
-void smb_netbios_cache_delete_locals(name_queue_t *delq);
-void smb_netbios_cache_refresh(name_queue_t *refq);
+void smb_netbios_cache_delete_locals(name_queue_t *);
+void smb_netbios_cache_refresh(name_queue_t *);
int smb_netbios_cache_insert(struct name_entry *name);
int smb_netbios_cache_insert_list(struct name_entry *name);
@@ -1550,23 +636,21 @@ void smb_netbios_cache_delete(struct name_entry *name);
int smb_netbios_cache_delete_addr(struct name_entry *name);
struct name_entry *smb_netbios_cache_lookup(struct name_entry *name);
struct name_entry *smb_netbios_cache_lookup_addr(struct name_entry *name);
-void smb_netbios_cache_update_entry(struct name_entry *entry,
- struct name_entry *name);
-void smb_netbios_cache_unlock_entry(struct name_entry *name);
-unsigned char *smb_netbios_cache_status(unsigned char *buf, int bufsize,
- unsigned char *scope);
+void smb_netbios_cache_update_entry(struct name_entry *, struct name_entry *);
+void smb_netbios_cache_unlock_entry(struct name_entry *);
+unsigned char *smb_netbios_cache_status(unsigned char *, int, unsigned char *);
+int smb_netbios_cache_getfirst(nbcache_iter_t *);
+int smb_netbios_cache_getnext(nbcache_iter_t *);
void smb_netbios_name_dump(struct name_entry *entry);
void smb_netbios_name_logf(struct name_entry *entry);
void smb_netbios_name_freeaddrs(struct name_entry *entry);
-struct name_entry *smb_netbios_name_dup(struct name_entry *entry,
- int alladdr);
+struct name_entry *smb_netbios_name_dup(struct name_entry *, int);
/* Name service functions */
void *smb_netbios_name_service_daemon(void *);
-void smb_init_name_struct(unsigned char *, char,
- unsigned char *, uint32_t, unsigned short,
- uint32_t, uint32_t, struct name_entry *);
+void smb_init_name_struct(unsigned char *, char, unsigned char *, uint32_t,
+ unsigned short, uint32_t, uint32_t, struct name_entry *);
struct name_entry *smb_name_find_name(struct name_entry *name);
int smb_name_add_name(struct name_entry *name);
@@ -1577,41 +661,24 @@ void smb_netbios_name_config(void);
void smb_netbios_name_unconfig(void);
void smb_netbios_name_tick(void);
-int smb_first_level_name_encode(struct name_entry *name,
- unsigned char *out, int max_out);
-int smb_first_level_name_decode(unsigned char *in,
- struct name_entry *name);
-void smb_encode_netbios_name(unsigned char *name,
- char suffix, unsigned char *scope,
- struct name_entry *dest);
+int smb_first_level_name_encode(struct name_entry *, unsigned char *, int);
+int smb_first_level_name_decode(unsigned char *, struct name_entry *);
+void smb_encode_netbios_name(unsigned char *, char, unsigned char *,
+ struct name_entry *);
/* Datagram service functions */
void *smb_netbios_datagram_service_daemon(void *);
int smb_netbios_datagram_send(struct name_entry *,
- struct name_entry *, unsigned char *, int);
+ struct name_entry *, unsigned char *, int);
void smb_netbios_datagram_tick(void);
-
/* browser functions */
-void smb_browser_config(void);
void *smb_browser_dispatch(void *arg);
void *smb_browser_daemon(void *);
-int smb_net_id(uint32_t ipaddr);
-struct name_entry *smb_browser_get_srvname(unsigned short netid);
-int smb_browser_load_transact_header(unsigned char *buffer,
- int maxcnt, int data_count, int reply, char *mailbox);
+int smb_browser_load_transact_header(unsigned char *, int, int, int, char *);
/* Netlogon function */
-/*
- * smb_netlogon_receive
- *
- * This is where we handle all incoming NetLogon messages. Currently, we
- * ignore requests from anyone else. We are only interested in responses
- * to our own requests. The NetLogonResponse provides the name of the PDC.
- * If we don't already have a controller name, we use the name provided
- * in the message. Otherwise we use the name already in the environment.
- */
-void smb_netlogon_receive(struct datagram *datagram, char *mailbox,
- unsigned char *data, int datalen);
+void smb_netlogon_receive(struct datagram *, char *, unsigned char *, int);
+void smb_netlogon_request(struct name_entry *, int, char *);
#endif /* _SMB_NETBIOS_H_ */
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
index a1c3bb2c03..dae42d4d7f 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
@@ -77,7 +77,7 @@ smb_netbios_cache_init()
}
void
-smb_netbios_cache_fini()
+smb_netbios_cache_fini(void)
{
(void) rw_wrlock(&nb_cache_lock);
ht_destroy_table(smb_netbios_cache);
@@ -86,13 +86,59 @@ smb_netbios_cache_fini()
}
void
-smb_netbios_cache_clean()
+smb_netbios_cache_clean(void)
{
(void) rw_wrlock(&nb_cache_lock);
(void) ht_clean_table(smb_netbios_cache);
(void) rw_unlock(&nb_cache_lock);
}
+int
+smb_netbios_cache_getfirst(nbcache_iter_t *iter)
+{
+ HT_ITEM *item;
+ struct name_entry *entry;
+
+ (void) rw_rdlock(&nb_cache_lock);
+ item = ht_findfirst(smb_netbios_cache, &iter->nbc_hti);
+ if (item == NULL || item->hi_data == NULL) {
+ (void) rw_unlock(&nb_cache_lock);
+ return (-1);
+ }
+
+ entry = (struct name_entry *)item->hi_data;
+ (void) mutex_lock(&entry->mtx);
+ iter->nbc_entry = smb_netbios_name_dup(entry, 1);
+ (void) mutex_unlock(&entry->mtx);
+
+ (void) rw_unlock(&nb_cache_lock);
+
+ return ((iter->nbc_entry) ? 0 : -1);
+}
+
+int
+smb_netbios_cache_getnext(nbcache_iter_t *iter)
+{
+ HT_ITEM *item;
+ struct name_entry *entry;
+
+ (void) rw_rdlock(&nb_cache_lock);
+ item = ht_findnext(&iter->nbc_hti);
+ if (item == NULL || item->hi_data == NULL) {
+ (void) rw_unlock(&nb_cache_lock);
+ return (-1);
+ }
+
+ entry = (struct name_entry *)item->hi_data;
+ (void) mutex_lock(&entry->mtx);
+ iter->nbc_entry = smb_netbios_name_dup(entry, 1);
+ (void) mutex_unlock(&entry->mtx);
+
+ (void) rw_unlock(&nb_cache_lock);
+
+ return ((iter->nbc_entry) ? 0 : -1);
+}
+
/*
* smb_netbios_cache_lookup
*
@@ -106,19 +152,15 @@ smb_netbios_cache_lookup(struct name_entry *name)
HT_ITEM *item;
nb_key_t key;
struct name_entry *entry = NULL;
- unsigned char scope[SMB_PI_MAX_SCOPE];
unsigned char hostname[MAXHOSTNAMELEN];
if (NETBIOS_NAME_IS_STAR(name->name)) {
/* Return our address */
- (void) smb_config_getstr(SMB_CI_NBSCOPE, (char *)scope,
- sizeof (scope));
- (void) utf8_strupr((char *)scope);
-
- if (smb_getnetbiosname((char *)hostname, MAXHOSTNAMELEN) != 0)
+ if (smb_getnetbiosname((char *)hostname, sizeof (hostname))
+ != 0)
return (NULL);
- smb_encode_netbios_name(hostname, 0x00, scope, name);
+ smb_encode_netbios_name(hostname, 0x00, NULL, name);
}
(void) rw_rdlock(&nb_cache_lock);
@@ -196,6 +238,7 @@ smb_netbios_cache_insert(struct name_entry *name)
struct addr_entry *name_addr;
HT_ITEM *item;
nb_key_t key;
+ int rc;
/* No point in adding a name with IP address 255.255.255.255 */
if (name->addr_list.sin.sin_addr.s_addr == 0xffffffff)
@@ -216,10 +259,9 @@ smb_netbios_cache_insert(struct name_entry *name)
(addr->sin.sin_port == name_addr->sin.sin_port)) {
entry->attributes |=
name_addr->attributes & NAME_ATTR_LOCAL;
- syslog(LOG_DEBUG, "cache_insert: exists");
(void) mutex_unlock(&entry->mtx);
(void) rw_unlock(&nb_cache_lock);
- return (0); /* exists */
+ return (0);
}
/* Was not primary: looks for others */
@@ -227,32 +269,31 @@ smb_netbios_cache_insert(struct name_entry *name)
addr != &entry->addr_list; addr = addr->forw) {
if (NETBIOS_SAME_IP(addr, name_addr) &&
(addr->sin.sin_port == name_addr->sin.sin_port)) {
- syslog(LOG_DEBUG, "cache_insert: dup");
(void) mutex_unlock(&entry->mtx);
(void) rw_unlock(&nb_cache_lock);
- return (0); /* exists */
+ return (0);
}
}
- addr = (struct addr_entry *)malloc(sizeof (struct addr_entry));
- if (addr == 0) {
- (void) mutex_unlock(&entry->mtx);
- (void) rw_unlock(&nb_cache_lock);
- return (-1);
+ if ((addr = malloc(sizeof (struct addr_entry))) != NULL) {
+ *addr = name->addr_list;
+ entry->attributes |= addr->attributes;
+ QUEUE_INSERT_TAIL(&entry->addr_list, addr);
+ rc = 0;
+ } else {
+ rc = -1;
}
- *addr = name->addr_list;
- entry->attributes |= addr->attributes;
- QUEUE_INSERT_TAIL(&entry->addr_list, addr);
+
(void) mutex_unlock(&entry->mtx);
(void) rw_unlock(&nb_cache_lock);
- return (0);
+ return (rc);
}
- entry = (struct name_entry *)malloc(sizeof (struct name_entry));
- if (entry == 0) {
+ if ((entry = malloc(sizeof (struct name_entry))) == NULL) {
(void) rw_unlock(&nb_cache_lock);
return (-1);
}
+
*entry = *name;
entry->addr_list.forw = entry->addr_list.back = &entry->addr_list;
entry->attributes |= entry->addr_list.attributes;
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c
index 2775ccfe7a..c280a89e28 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c
@@ -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.
*/
@@ -323,7 +323,6 @@ smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest,
char *buffer;
char ha_source[NETBIOS_DOMAIN_NAME_MAX];
char ha_dest[NETBIOS_DOMAIN_NAME_MAX];
- net_cfg_t cfg;
(void) smb_first_level_name_encode(src, (unsigned char *)ha_source,
sizeof (ha_source));
@@ -378,9 +377,8 @@ smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest,
do {
ipaddr = addr->sin.sin_addr.s_addr;
/* Don't send anything to myself... */
- if (smb_nic_get_byip(ipaddr, &cfg) != NULL) {
+ if (smb_nic_exists(ipaddr, B_FALSE))
goto next;
- }
sin.sin_addr.s_addr = ipaddr;
sin.sin_port = addr->sin.sin_port;
@@ -405,7 +403,6 @@ smb_netbios_datagram_send_to_net(struct name_entry *src,
char *buffer;
char ha_source[NETBIOS_DOMAIN_NAME_MAX];
char ha_dest[NETBIOS_DOMAIN_NAME_MAX];
- net_cfg_t cfg;
(void) smb_first_level_name_encode(src, (unsigned char *)ha_source,
sizeof (ha_source));
@@ -459,9 +456,9 @@ smb_netbios_datagram_send_to_net(struct name_entry *src,
addr = &dest->addr_list;
do {
ipaddr = addr->sin.sin_addr.s_addr;
- if (smb_nic_get_byip(ipaddr, &cfg) != NULL) {
+ if (smb_nic_exists(ipaddr, B_FALSE))
goto next;
- }
+
sin.sin_addr.s_addr = ipaddr;
sin.sin_port = addr->sin.sin_port;
(void) sendto(datagram_sock, buffer, count, 0,
@@ -954,7 +951,6 @@ smb_netbios_datagram_service_daemon(void *arg)
struct sockaddr_in sin;
struct datagram *datagram;
int bytes, flag = 1;
- net_cfg_t cfg;
(void) mutex_lock(&smb_dgq_mtx);
bzero(&smb_datagram_queue, sizeof (smb_datagram_queue));
@@ -1009,11 +1005,11 @@ ignore: bzero(&datagram->inaddr, sizeof (struct addr_entry));
}
/* Ignore any incoming packets from myself... */
- if (smb_nic_get_byip(
- datagram->inaddr.sin.sin_addr.s_addr,
- &cfg) != NULL) {
+ if (smb_nic_exists(datagram->inaddr.sin.sin_addr.s_addr,
+ B_FALSE)) {
goto ignore;
}
+
if (smb_datagram_decode(datagram, bytes) < 0)
goto ignore;
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
index f7794479ab..7054d4bfae 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
@@ -588,11 +588,10 @@ strnchr(const char *s, char c, int n)
return (0);
}
-/*ARGSUSED*/
-static int
+static boolean_t
is_multihome(char *name)
{
- return ((smb_nic_get_num() > 1) ? 1 : 0);
+ return (smb_nic_getnum(name) > 1);
}
/*
@@ -1976,9 +1975,11 @@ smb_send_name_query_response(struct addr_entry *addr,
NAME_ATTR_OWNER_NODE_TYPE);
BE_OUT16(scan, attr); scan += 2;
- (void) memcpy(scan, &raddr->sin.sin_addr.s_addr,
- sizeof (uint32_t));
- scan += 4;
+
+ *scan++ = raddr->sin.sin_addr.s_addr;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 8;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 16;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 24;
answer.rdlength += 6;
raddr = raddr->forw;
@@ -2134,7 +2135,6 @@ smb_send_node_status_response(struct addr_entry *addr,
unsigned char *scan;
unsigned char *scan_end;
unsigned char data[MAX_NETBIOS_REPLY_DATA_SIZE];
- net_cfg_t cfg;
boolean_t scan_done = B_FALSE;
bzero(&packet, sizeof (struct name_packet));
@@ -2162,10 +2162,10 @@ smb_send_node_status_response(struct addr_entry *addr,
scan_end = data + MAX_NETBIOS_REPLY_DATA_SIZE;
- if (smb_nic_get_bysubnet(addr->sin.sin_addr.s_addr, &cfg) == NULL)
- net_ipaddr = 0;
+ if (smb_nic_exists(addr->sin.sin_addr.s_addr, B_TRUE))
+ net_ipaddr = addr->sin.sin_addr.s_addr;
else
- net_ipaddr = cfg.ip;
+ net_ipaddr = 0;
(void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections);
@@ -2575,9 +2575,11 @@ smb_name_Bnode_delete_name(struct name_entry *name)
NAME_ATTR_OWNER_NODE_TYPE);
BE_OUT16(scan, attr); scan += 2;
- (void) memcpy(scan, &raddr->sin.sin_addr.s_addr,
- sizeof (uint32_t));
- scan += 4;
+
+ *scan++ = raddr->sin.sin_addr.s_addr;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 8;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 16;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 24;
additional.rdlength += 6;
} while (raddr != &name->addr_list);
@@ -3010,10 +3012,11 @@ smb_name_Pnode_delete_name(struct name_entry *name)
NAME_ATTR_OWNER_NODE_TYPE);
BE_OUT16(scan, attr); scan += 2;
- BE_OUT32(scan, raddr->sin.sin_addr.s_addr); scan += 4;
- (void) memcpy(scan, &raddr->sin.sin_addr.s_addr,
- sizeof (uint32_t));
- scan += 4;
+
+ *scan++ = raddr->sin.sin_addr.s_addr;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 8;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 16;
+ *scan++ = raddr->sin.sin_addr.s_addr >> 24;
additional.rdlength = 6;
raddr = raddr->forw;
@@ -4472,9 +4475,7 @@ smb_netbios_worker(void *arg)
if (packet->answer)
smb_netbios_name_freeaddrs(packet->answer->name);
free(packet);
- }
- else
- {
+ } else {
syslog(LOG_DEBUG, "SmbNBNS: error decoding received packet");
}
@@ -4497,33 +4498,62 @@ smb_netbios_wins_config(char *ip)
smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr;
smb_nbns[nbns_num++].sin.sin_port =
htons(NAME_SERVICE_UDP_PORT);
- smb_node_type = 'H';
+ smb_node_type = SMB_NODETYPE_H;
+ }
+}
+
+static void
+smb_netbios_name_registration(void)
+{
+ nbcache_iter_t nbc_iter;
+ struct name_entry *name;
+ int rc;
+
+ rc = smb_netbios_cache_getfirst(&nbc_iter);
+ while (rc == 0) {
+ name = nbc_iter.nbc_entry;
+ (void) smb_netbios_name_logf(name);
+ if (IS_UNIQUE(name->attributes) && IS_LOCAL(name->attributes)) {
+ switch (smb_node_type) {
+ case SMB_NODETYPE_B:
+ (void) smb_name_Bnode_add_name(name);
+ break;
+ case SMB_NODETYPE_P:
+ (void) smb_name_Pnode_add_name(name);
+ break;
+ case SMB_NODETYPE_M:
+ (void) smb_name_Mnode_add_name(name);
+ break;
+ case SMB_NODETYPE_H:
+ default:
+ (void) smb_name_Hnode_add_name(name);
+ break;
+ }
+ }
+ free(name);
+ rc = smb_netbios_cache_getnext(&nbc_iter);
}
}
void
smb_netbios_name_config(void)
{
- uint32_t ipaddr;
struct name_entry name;
- char myname[MAXHOSTNAMELEN];
- int i;
- int smb_nc_cnt;
- net_cfg_t cfg;
char wins_ip[16];
-
- if (smb_getnetbiosname(myname, MAXHOSTNAMELEN) != 0)
- return;
+ smb_niciter_t ni;
+ int rc;
/* Start with no broadcast addresses */
bcast_num = 0;
bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
- smb_nc_cnt = smb_nic_get_num();
- /* Add all of my broadcast addresses */
- for (i = 0; i < smb_nc_cnt; i++) {
- if (smb_nic_get_byind(i, &cfg) == NULL) {
- break;
+ /* Add all of the broadcast addresses */
+ rc = smb_nic_getfirst(&ni);
+ while (rc == 0) {
+ if (ni.ni_nic.nic_smbflags &
+ (SMB_NICF_ALIAS | SMB_NICF_NBEXCL)) {
+ rc = smb_nic_getnext(&ni);
+ continue;
}
smb_bcast_list[bcast_num].flags = ADDR_FLAG_VALID;
smb_bcast_list[bcast_num].attributes = NAME_ATTR_LOCAL;
@@ -4532,11 +4562,12 @@ smb_netbios_name_config(void)
smb_bcast_list[bcast_num].sin.sin_port =
htons(NAME_SERVICE_UDP_PORT);
smb_bcast_list[bcast_num++].sin.sin_addr.s_addr =
- cfg.broadcast;
+ ni.ni_nic.nic_bcast;
+ rc = smb_nic_getnext(&ni);
}
/* Start with no WINS */
- smb_node_type = 'B';
+ smb_node_type = SMB_NODETYPE_B;
nbns_num = 0;
bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
@@ -4546,24 +4577,25 @@ smb_netbios_name_config(void)
(void) smb_config_getstr(SMB_CI_WINS_SRV2, wins_ip, sizeof (wins_ip));
smb_netbios_wins_config(wins_ip);
- for (i = 0; i < smb_nc_cnt; i++) {
- if (smb_nic_get_byind(i, &cfg) == NULL) {
- break;
- }
- if (cfg.exclude)
+ if (smb_nic_getfirst(&ni) != 0)
+ return;
+
+ do {
+ if (ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL)
continue;
- ipaddr = cfg.ip;
- smb_init_name_struct((unsigned char *)myname, 0x00, 0, ipaddr,
- htons(DGM_SRVC_UDP_PORT), NAME_ATTR_UNIQUE,
- NAME_ATTR_LOCAL, &name);
- (void) smb_name_add_name(&name);
+ smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
+ 0x00, 0, ni.ni_nic.nic_ip, htons(DGM_SRVC_UDP_PORT),
+ NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
+ (void) smb_netbios_cache_insert(&name);
- smb_init_name_struct((unsigned char *)myname, 0x20, 0,
- ipaddr, htons(DGM_SRVC_UDP_PORT),
+ smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
+ 0x20, 0, ni.ni_nic.nic_ip, htons(DGM_SRVC_UDP_PORT),
NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
- (void) smb_name_add_name(&name);
- }
+ (void) smb_netbios_cache_insert(&name);
+ } while (smb_nic_getnext(&ni) == 0);
+
+ smb_netbios_name_registration();
}
void
@@ -4612,7 +4644,6 @@ smb_netbios_name_service_daemon(void *arg)
int flag = 1;
char *buf;
worker_param_t *worker_param;
- net_cfg_t cfg;
/*
* Initialize reply_queue
@@ -4689,10 +4720,8 @@ ignore: bzero(addr, sizeof (struct addr_entry));
}
/* Ignore any incoming packets from myself... */
- if (smb_nic_get_byip(addr->sin.sin_addr.s_addr,
- &cfg) != NULL) {
+ if (smb_nic_exists(addr->sin.sin_addr.s_addr, B_FALSE))
goto ignore;
- }
/*
* Launch a netbios worker to process the received packet.
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
index 2631bd0f68..6f99711a7c 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
@@ -74,29 +74,24 @@ static char resource_domain[SMB_PI_MAX_DOMAIN];
* in smb_netlogon_receive.
*/
void
-smb_netlogon_request(int net, int protocol, char *domain)
+smb_netlogon_request(struct name_entry *server, int protocol, char *domain)
{
- struct name_entry *server;
nt_domain_t *ntdp;
- server = smb_browser_get_srvname(net);
- if (server == 0)
+ if (domain == NULL || *domain == '\0')
return;
- (void) strlcpy(resource_domain, domain,
- sizeof (resource_domain));
-
- if (strlen(resource_domain) > 0) {
- ntdp = nt_domain_lookup_name(resource_domain);
- if (protocol == NETLOGON_PROTO_SAMLOGON && ntdp)
- smb_netlogon_samlogon(server,
- MAILSLOT_NETLOGON_SAMLOGON_RDC,
- resource_domain);
- else
- smb_netlogon_query(server,
- MAILSLOT_NETLOGON_RDC,
- resource_domain);
- }
+ (void) strlcpy(resource_domain, domain, sizeof (resource_domain));
+
+ ntdp = nt_domain_lookup_name(resource_domain);
+ if (ntdp && (protocol == NETLOGON_PROTO_SAMLOGON))
+ smb_netlogon_samlogon(server,
+ MAILSLOT_NETLOGON_SAMLOGON_RDC,
+ resource_domain);
+ else
+ smb_netlogon_query(server,
+ MAILSLOT_NETLOGON_RDC,
+ resource_domain);
}
/*
@@ -521,8 +516,6 @@ smb_netlogon_rdc_rsp(char *src_name, uint32_t src_ipaddr)
static int
better_dc(uint32_t cur_ip, uint32_t new_ip)
{
- net_cfg_t cfg;
-
/*
* If we don't have any current DC,
* then use the new one of course.
@@ -530,9 +523,10 @@ better_dc(uint32_t cur_ip, uint32_t new_ip)
if (cur_ip == 0)
return (1);
- if (smb_nic_get_bysubnet(cur_ip, &cfg) != NULL)
+ if (smb_nic_exists(cur_ip, B_TRUE))
return (0);
- if (smb_nic_get_bysubnet(new_ip, &cfg) != NULL)
+
+ if (smb_nic_exists(new_ip, B_TRUE))
return (1);
/*
* Otherwise, just keep the old one.
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c
deleted file mode 100644
index fc812e2567..0000000000
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c
+++ /dev/null
@@ -1,493 +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"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <libintl.h>
-#include <strings.h>
-#include <unistd.h>
-#include <synch.h>
-#include <stropts.h>
-#include <errno.h>
-#include <pthread.h>
-
-#include <inet/ip.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <net/route.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/systeminfo.h>
-
-#include <smbsrv/libsmbns.h>
-
-#define MAXIFS 256
-
-typedef struct smb_ifnames {
- char *if_names[MAXIFS];
- int if_num;
-} smb_ifnames_t;
-
-typedef struct {
- net_cfg_t *nl_nics;
- int nl_cnt;
-} smb_niclist_t;
-
-static int smb_nic_iflist_create(smb_ifnames_t *);
-static void smb_nic_iflist_destroy(smb_ifnames_t *);
-
-static int smb_niclist_create(void);
-static void smb_niclist_destroy(void);
-static void smb_niclist_lock(void);
-static void smb_niclist_unlock(void);
-
-/* This is the list we will monitor */
-static smb_niclist_t smb_niclist = { NULL, 0 };
-static pthread_mutex_t smb_niclist_mtx = PTHREAD_MUTEX_INITIALIZER;
-
-int
-smb_get_nameservers(struct in_addr *ips, int sz)
-{
- union res_sockaddr_union set[MAXNS];
- int i, cnt;
- struct __res_state res_state;
-
- if (ips == NULL)
- return (0);
-
- bzero(&res_state, sizeof (struct __res_state));
- if (res_ninit(&res_state) < 0)
- return (0);
-
- cnt = res_getservers(&res_state, set, MAXNS);
- for (i = 0; i < cnt; i++) {
- if (i >= sz)
- break;
- ips[i] = set[i].sin.sin_addr;
- syslog(LOG_DEBUG, "NS Found %s name server\n",
- inet_ntoa(ips[i]));
- }
- syslog(LOG_DEBUG, "NS Found %d name servers\n", i);
- res_ndestroy(&res_state);
- return (i);
-}
-
-/*
- * Initialize interface list.
- */
-void
-smb_nic_build_info(void)
-{
- smb_niclist_lock();
- smb_niclist_destroy();
-
- if (smb_niclist_create() < 0)
- syslog(LOG_ERR, "smbd: failed getting network interfaces"
- " information");
- else if (smb_niclist.nl_cnt == 0)
- syslog(LOG_ERR, "smbd: No network interfaces are configured "
- "smb server may not function properly");
-
- smb_niclist_unlock();
-}
-
-/*
- * Get number of interfaces.
- */
-int
-smb_nic_get_num(void)
-{
- int n;
-
- smb_niclist_lock();
- n = smb_niclist.nl_cnt;
- smb_niclist_unlock();
-
- return (n);
-}
-
-/*
- * Get if by index
- * Returns: NULL if not found.
- */
-net_cfg_t *
-smb_nic_get_byind(int ind, net_cfg_t *cfg)
-{
- if (cfg == NULL)
- return (NULL);
-
- smb_niclist_lock();
- if (ind > smb_niclist.nl_cnt) {
- smb_niclist_unlock();
- return (NULL);
- }
- bcopy(&smb_niclist.nl_nics[ind], cfg, sizeof (net_cfg_t));
- smb_niclist_unlock();
-
- return (cfg);
-}
-
-/*
- * Get if by subnet
- * Returns: NULL if not found.
- */
-net_cfg_t *
-smb_nic_get_bysubnet(uint32_t ipaddr, net_cfg_t *cfg)
-{
- net_cfg_t *tcfg;
- int i;
-
- if (cfg == NULL)
- return (NULL);
-
- bzero(cfg, sizeof (net_cfg_t));
-
- smb_niclist_lock();
- for (i = 0; i < smb_niclist.nl_cnt; i++) {
- tcfg = &smb_niclist.nl_nics[i];
- if ((ipaddr & tcfg->mask) ==
- (tcfg->ip & tcfg->mask)) {
- bcopy(tcfg, cfg, sizeof (net_cfg_t));
- smb_niclist_unlock();
- return (cfg);
- }
- }
- smb_niclist_unlock();
-
- return (NULL);
-}
-
-/*
- * Get if by ip.
- * Returns: NULL if not found.
- */
-net_cfg_t *
-smb_nic_get_byip(uint32_t ipaddr, net_cfg_t *cfg)
-{
- net_cfg_t *tcfg;
- int i;
-
- if (cfg == NULL)
- return (NULL);
-
- bzero(cfg, sizeof (net_cfg_t));
-
- smb_niclist_lock();
- for (i = 0; i < smb_niclist.nl_cnt; i++) {
- tcfg = &smb_niclist.nl_nics[i];
- if (ipaddr == tcfg->ip) {
- bcopy(tcfg, cfg, sizeof (net_cfg_t));
- smb_niclist_unlock();
- return (cfg);
- }
- }
- smb_niclist_unlock();
-
- return (NULL);
-}
-
-/*
- * The following list is taken from if.h. The function takes the
- * given interface name, and the passed flag(s), and returns true if
- * the flag is associated with the interface, and false if not.
- *
- * IFF_UP interface is up
- * IFF_BROADCAST broadcast address valid
- * IFF_LOOPBACK is a loopback net
- * IFF_POINTOPOINT interface is point-to-point link
- * IFF_RUNNING resources allocated
- * IFF_MULTICAST supports multicast
- * IFF_MULTI_BCAST multicast using broadcast address
- * IFF_UNNUMBERED non-unique address
- * IFF_DHCPRUNNING DHCP controls this interface
- * IFF_PRIVATE do not advertise
- * IFF_DEPRECATED interface address deprecated
- * IFF_ANYCAST Anycast address
- * IFF_IPV4 IPv4 interface
- * IFF_IPV6 IPv6 interface
- * IFF_NOFAILOVER Don't failover on NIC failure
- * IFF_FAILED NIC has failed
- * IFF_STANDBY Standby NIC to be used on failures
- * IFF_OFFLINE NIC has been offlined
- */
-boolean_t
-smb_nic_status(char *interface, uint64_t flag)
-{
- struct lifreq lifrr;
- int rc;
- int s;
-
- if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
- syslog(LOG_DEBUG, "smb_nic_status: %s", strerror(errno));
- return (B_FALSE);
- }
-
- (void) strlcpy(lifrr.lifr_name, interface, sizeof (lifrr.lifr_name));
- rc = ioctl(s, SIOCGLIFFLAGS, &lifrr);
- (void) close(s);
-
- if (rc < 0) {
- syslog(LOG_DEBUG, "smb_nic_status: %s", strerror(errno));
- return (B_FALSE);
- }
-
- if (lifrr.lifr_flags & flag)
- return (B_TRUE);
-
- return (B_FALSE);
-}
-
-/*
- * Get IP info and more for the given interface
- */
-static int
-smb_nic_getinfo(char *interface, net_cfg_t *nc)
-{
- struct lifreq lifrr;
- struct sockaddr_in *sa;
- int s;
-
- if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
- return (-1);
- }
-
- (void) strlcpy(lifrr.lifr_name, interface, sizeof (lifrr.lifr_name));
- if (ioctl(s, SIOCGLIFADDR, &lifrr) < 0) {
- (void) close(s);
- return (-1);
- }
- sa = (struct sockaddr_in *)&lifrr.lifr_addr;
- nc->ip = (uint32_t)sa->sin_addr.s_addr;
-
- if (ioctl(s, SIOCGLIFBRDADDR, &lifrr) < 0) {
- (void) close(s);
- return (-1);
- }
- sa = (struct sockaddr_in *)&lifrr.lifr_broadaddr;
- nc->broadcast = (uint32_t)sa->sin_addr.s_addr;
-
- if (ioctl(s, SIOCGLIFNETMASK, &lifrr) < 0) {
- (void) close(s);
- return (-1);
- }
- sa = (struct sockaddr_in *)&lifrr.lifr_addr;
- nc->mask = (uint32_t)sa->sin_addr.s_addr;
-
- if (ioctl(s, SIOCGLIFFLAGS, &lifrr) < 0) {
- (void) close(s);
- return (-1);
- }
- nc->flags = lifrr.lifr_flags;
-
- (void) strlcpy(nc->ifname, interface, sizeof (nc->ifname));
-
- (void) close(s);
- return (0);
-}
-
-/*
- * Get the list of currently plumbed interface names. The loopback (lo0)
- * port is ignored
- */
-static int
-smb_nic_iflist_create(smb_ifnames_t *iflist)
-{
- struct ifconf ifc;
- struct ifreq ifr;
- struct ifreq *ifrp;
- char *ifname;
- int ifnum;
- int i;
- int s;
-
- bzero(iflist, sizeof (smb_ifnames_t));
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- return (-1);
-
- if (ioctl(s, SIOCGIFNUM, (char *)&ifnum) < 0) {
- (void) close(s);
- return (-1);
- }
-
- ifc.ifc_len = ifnum * sizeof (struct ifreq);
- ifc.ifc_buf = malloc(ifc.ifc_len);
- if (ifc.ifc_buf == NULL) {
- (void) close(s);
- return (-1);
- }
- bzero(ifc.ifc_buf, ifc.ifc_len);
-
- if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
- (void) close(s);
- free(ifc.ifc_buf);
- return (-1);
- }
-
- ifrp = ifc.ifc_req;
- ifnum = ifc.ifc_len / sizeof (struct ifreq);
-
- for (i = 0; i < ifnum; i++, ifrp++) {
- /*
- * Get the flags so that we can skip the loopback interface
- */
- (void) memset(&ifr, 0, sizeof (ifr));
- (void) strlcpy(ifr.ifr_name, ifrp->ifr_name,
- sizeof (ifr.ifr_name));
-
- if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
- (void) close(s);
- free(ifc.ifc_buf);
- smb_nic_iflist_destroy(iflist);
- return (-1);
- }
-
- if (ifr.ifr_flags & IFF_LOOPBACK)
- continue;
-
- if ((ifr.ifr_flags & IFF_UP) == 0)
- continue;
-
- ifname = strdup(ifrp->ifr_name);
- if (ifname == NULL) {
- (void) close(s);
- free(ifc.ifc_buf);
- smb_nic_iflist_destroy(iflist);
- return (-1);
- }
- iflist->if_names[iflist->if_num++] = ifname;
- }
-
- (void) close(s);
- free(ifc.ifc_buf);
- return (0);
-}
-
-/*
- * Frees allocated memory for the given IF names lists.
- */
-static void
-smb_nic_iflist_destroy(smb_ifnames_t *iflist)
-{
- int i;
-
- if (iflist == NULL)
- return;
-
- for (i = 0; i < iflist->if_num; i++)
- free(iflist->if_names[i]);
-}
-
-/*
- * This will mimick the workings of ifconfig -a command.
- *
- * Note that the caller of this function should grab the
- * list lock.
- */
-static int
-smb_niclist_create(void)
-{
- smb_ifnames_t ifnames;
- net_cfg_t *nc;
- char *ifname;
- char excludestr[MAX_EXCLUDE_LIST_LEN];
- ipaddr_t exclude[SMB_PI_MAX_NETWORKS];
- int nexclude;
- int i;
-
- if (smb_nic_iflist_create(&ifnames) < 0)
- return (-1);
-
- smb_niclist.nl_nics = calloc(ifnames.if_num, sizeof (net_cfg_t));
- if (smb_niclist.nl_nics == NULL) {
- smb_nic_iflist_destroy(&ifnames);
- return (-1);
- }
-
- (void) smb_config_getstr(SMB_CI_WINS_EXCL, excludestr,
- sizeof (excludestr));
- nexclude = smb_wins_iplist(excludestr, exclude, SMB_PI_MAX_NETWORKS);
-
- nc = smb_niclist.nl_nics;
- for (i = 0; i < ifnames.if_num; i++, nc++) {
- ifname = ifnames.if_names[i];
- if (strchr(ifname, ':'))
- /* Will not provide info on logical interfaces */
- continue;
-
- if (smb_nic_getinfo(ifname, nc) < 0) {
- smb_nic_iflist_destroy(&ifnames);
- smb_niclist_destroy();
- return (-1);
- }
- smb_niclist.nl_cnt++;
-
- if (smb_wins_is_excluded(nc->ip,
- (ipaddr_t *)exclude, nexclude))
- nc->exclude = B_TRUE;
- }
-
- smb_nic_iflist_destroy(&ifnames);
-
- return (0);
-}
-
-static void
-smb_niclist_destroy(void)
-{
- free(smb_niclist.nl_nics);
- smb_niclist.nl_nics = NULL;
- smb_niclist.nl_cnt = 0;
-}
-
-/*
- * smb_niclist_lock
- *
- * Lock the nic table
- */
-static void
-smb_niclist_lock(void)
-{
- (void) pthread_mutex_lock(&smb_niclist_mtx);
-}
-
-/*
- * smb_niclist_unlock
- *
- * Unlock the nic table.
- */
-static void
-smb_niclist_unlock(void)
-{
- (void) pthread_mutex_unlock(&smb_niclist_mtx);
-}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_check_directory.c b/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
index 9d6d0c202d..b2ca8db4a5 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
@@ -67,7 +67,7 @@
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
-int
+smb_sdrc_t
smb_com_check_directory(struct smb_request *sr)
{
int rc;
@@ -76,20 +76,18 @@ smb_com_check_directory(struct smb_request *sr)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- if (smbsr_decode_data(sr, "%S", sr, &sr->arg.dirop.fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%S", sr, &sr->arg.dirop.fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
sr->arg.dirop.fqi.srch_attr = 0;
rc = smbd_fs_query(sr, &sr->arg.dirop.fqi, FQM_PATH_MUST_EXIST);
if (rc) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -105,7 +103,7 @@ smb_com_check_directory(struct smb_request *sr)
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
smbsr_errno(sr, ENOTDIR);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_fsop_access(sr, sr->user_cr, dnode, FILE_TRAVERSE);
@@ -116,10 +114,9 @@ smb_com_check_directory(struct smb_request *sr)
if (rc != 0) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_empty_result(sr);
-
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_close.c b/usr/src/uts/common/fs/smbsrv/smb_close.c
index f2d7faeb8d..988ba3697d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_close.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_close.c
@@ -39,54 +39,50 @@
* Failure to set the timestamp, even if requested by the client,
* should not result in an error response from the server.
*/
-int
+smb_sdrc_t
smb_com_close(struct smb_request *sr)
{
uint32_t last_wtime;
int rc = 0;
rc = smbsr_decode_vwv(sr, "wl", &sr->smb_fid, &last_wtime);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_common_close(sr, last_wtime);
if (rc) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
* Close the file represented by fid and then disconnect the
* associated tree.
*/
-int
+smb_sdrc_t
smb_com_close_and_tree_disconnect(struct smb_request *sr)
{
uint32_t last_wtime;
int rc = 0;
rc = smbsr_decode_vwv(sr, "wl", &sr->smb_fid, &last_wtime);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_common_close(sr, last_wtime);
@@ -95,11 +91,11 @@ smb_com_close_and_tree_disconnect(struct smb_request *sr)
if (rc) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_open.c b/usr/src/uts/common/fs/smbsrv/smb_common_open.c
index 5e0d94976b..7b902a2835 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c
@@ -39,7 +39,9 @@
#include <sys/fcntl.h>
#include <sys/nbmlock.h>
-extern uint32_t smb_is_executable(char *path);
+extern uint32_t smb_is_executable(char *);
+
+static uint32_t smb_open_subr(smb_request_t *);
/*
* The default stability mode is to perform the write-through
@@ -207,6 +209,42 @@ smb_ofun_to_crdisposition(uint16_t ofun)
}
/*
+ * Retry opens to avoid spurious sharing violations, due to timing
+ * issues between closes and opens. The client that already has the
+ * file open may be in the process of closing it.
+ */
+uint32_t
+smb_common_open(smb_request_t *sr)
+{
+ uint32_t status = NT_STATUS_SUCCESS;
+ int count;
+
+ for (count = 0; count <= 4; count++) {
+ if (count)
+ delay(MSEC_TO_TICK(400));
+
+ if ((status = smb_open_subr(sr)) == NT_STATUS_SUCCESS)
+ break;
+ }
+
+ switch (status) {
+ case NT_STATUS_SUCCESS:
+ break;
+
+ case NT_STATUS_SHARING_VIOLATION:
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
+ ERRDOS, ERROR_SHARING_VIOLATION);
+ break;
+
+ default:
+ /* Error already set. */
+ break;
+ }
+
+ return (status);
+}
+
+/*
* smb_open_subr
*
* Notes on write-through behaviour. It looks like pre-LM0.12 versions
@@ -229,8 +267,8 @@ smb_ofun_to_crdisposition(uint16_t ofun)
* handle things in here.
*/
-uint32_t
-smb_open_subr(struct smb_request *sr)
+static uint32_t
+smb_open_subr(smb_request_t *sr)
{
int created = 0;
struct smb_node *node = 0;
@@ -247,7 +285,7 @@ smb_open_subr(struct smb_request *sr)
uint32_t status = NT_STATUS_SUCCESS;
int is_dir;
smb_error_t err;
- int is_stream;
+ int is_stream = 0;
int lookup_flags = SMB_FOLLOW_LINKS;
uint32_t daccess;
uint32_t share_access = op->share_access;
@@ -257,17 +295,16 @@ smb_open_subr(struct smb_request *sr)
if (is_dir) {
/*
- * The file being created or opened is a directory file.
- * With this flag, the Disposition parameter must be set to
- * one of FILE_CREATE, FILE_OPEN, or FILE_OPEN_IF
+ * The object being created or opened is a directory,
+ * and the Disposition parameter must be one of
+ * FILE_CREATE, FILE_OPEN, or FILE_OPEN_IF
*/
if ((op->create_disposition != FILE_CREATE) &&
(op->create_disposition != FILE_OPEN_IF) &&
(op->create_disposition != FILE_OPEN)) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_ACCESS);
- /* invalid open mode */
- /* NOTREACHED */
+ return (NT_STATUS_INVALID_PARAMETER);
}
}
@@ -278,7 +315,6 @@ smb_open_subr(struct smb_request *sr)
op->desired_access = smb_access_generic_to_file(op->desired_access);
if (sr->session->s_file_cnt >= SMB_SESSION_OFILE_MAX) {
-
ASSERT(sr->uid_user);
cmn_err(CE_NOTE, "smbd[%s\\%s]: %s", sr->uid_user->u_domain,
sr->uid_user->u_name,
@@ -286,7 +322,7 @@ smb_open_subr(struct smb_request *sr)
smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
- /* NOTREACHED */
+ return (NT_STATUS_TOO_MANY_OPENED_FILES);
}
/* This must be NULL at this point */
@@ -303,23 +339,19 @@ smb_open_subr(struct smb_request *sr)
* No further processing for IPC, we need to either
* raise an exception or return success here.
*/
- if ((rc = smb_rpc_open(sr)) != 0) {
- smbsr_error(sr, rc, 0, 0);
- /* NOTREACHED */
- } else {
- return (NT_STATUS_SUCCESS);
- }
- break;
+ if ((status = smb_rpc_open(sr)) != NT_STATUS_SUCCESS)
+ smbsr_error(sr, status, 0, 0);
+ return (status);
default:
- smbsr_error(sr, 0, ERRSRV, ERRinvdevice);
- /* NOTREACHED */
- break;
+ smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
+ ERRDOS, ERROR_BAD_DEV_TYPE);
+ return (NT_STATUS_BAD_DEVICE_TYPE);
}
if ((pathlen = strlen(op->fqi.path)) >= MAXPATHLEN) {
smbsr_error(sr, 0, ERRSRV, ERRfilespecs);
- /* NOTREACHED */
+ return (NT_STATUS_NAME_TOO_LONG);
}
/*
@@ -334,7 +366,7 @@ smb_open_subr(struct smb_request *sr)
if ((status = smb_validate_object_name(op->fqi.path, is_dir)) != 0) {
smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
- /* NOTREACHED */
+ return (status);
}
cur_node = op->fqi.dir_snode ?
@@ -344,7 +376,7 @@ smb_open_subr(struct smb_request *sr)
sr->tid_tree->t_snode, cur_node, &op->fqi.dir_snode,
op->fqi.last_comp)) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (sr->smb_error.status);
}
/*
@@ -376,7 +408,7 @@ smb_open_subr(struct smb_request *sr)
smb_node_release(op->fqi.dir_snode);
SMB_NULL_FQI_NODES(op->fqi);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (sr->smb_error.status);
}
/*
@@ -411,7 +443,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (NT_STATUS_FILE_IS_A_DIRECTORY);
}
if (op->fqi.last_attr.sa_vattr.va_type == VDIR) {
@@ -427,7 +459,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (NT_STATUS_FILE_IS_A_DIRECTORY);
}
} else if (op->my_flags & MYF_MUST_BE_DIRECTORY) {
rw_exit(&node->n_share_lock);
@@ -436,7 +468,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
ERRDOS, ERROR_DIRECTORY);
- /* NOTREACHED */
+ return (NT_STATUS_NOT_A_DIRECTORY);
}
/*
@@ -450,7 +482,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_DELETE_PENDING,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (NT_STATUS_DELETE_PENDING);
}
/*
@@ -463,7 +495,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
ERRDOS, ERROR_ALREADY_EXISTS);
- /* NOTREACHED */
+ return (NT_STATUS_OBJECT_NAME_COLLISION);
}
/*
@@ -481,7 +513,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (NT_STATUS_ACCESS_DENIED);
}
}
}
@@ -503,6 +535,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
+ return (NT_STATUS_ACCESS_DENIED);
}
}
@@ -531,9 +564,11 @@ smb_open_subr(struct smb_request *sr)
if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
smbsr_error(sr, status,
ERRDOS, ERROR_PRIVILEGE_NOT_HELD);
+ return (status);
} else {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
+ return (NT_STATUS_ACCESS_DENIED);
}
}
@@ -553,7 +588,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, status,
ERRDOS, ERROR_VC_DISCONNECTED);
- /* NOTREACHED */
+ return (status);
}
}
@@ -569,7 +604,7 @@ smb_open_subr(struct smb_request *sr)
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (NT_STATUS_ACCESS_DENIED);
}
if (node->attr.sa_vattr.va_size != op->dsize) {
@@ -589,7 +624,7 @@ smb_open_subr(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (sr->smb_error.status);
}
op->dsize = op->fqi.last_attr.sa_vattr.va_size;
@@ -618,13 +653,15 @@ smb_open_subr(struct smb_request *sr)
/* Last component was not found. */
dnode = op->fqi.dir_snode;
+ if (is_dir == 0)
+ is_stream = smb_stream_parse_name(op->fqi.path,
+ NULL, NULL);
+
if ((op->create_disposition == FILE_OPEN) ||
(op->create_disposition == FILE_OVERWRITE)) {
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- is_stream = smb_stream_parse_name(op->fqi.path,
- NULL, NULL);
/*
* The requested file not found so the operation should
* fail with these two dispositions
@@ -634,7 +671,8 @@ smb_open_subr(struct smb_request *sr)
ERRDOS, ERROR_FILE_NOT_FOUND);
else
smbsr_error(sr, 0, ERRDOS, ERRbadfile);
- /* NOTREACHED */
+
+ return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
}
/*
@@ -646,7 +684,9 @@ smb_open_subr(struct smb_request *sr)
bzero(&new_attr, sizeof (new_attr));
if (is_dir == 0) {
new_attr.sa_vattr.va_type = VREG;
- new_attr.sa_vattr.va_mode = 0666;
+ new_attr.sa_vattr.va_mode = is_stream ? S_IRUSR :
+ S_IRUSR | S_IRGRP | S_IROTH |
+ S_IWUSR | S_IWGRP | S_IWOTH;
new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
/*
@@ -678,7 +718,7 @@ smb_open_subr(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (sr->smb_error.status);
}
if (op->dattr & SMB_FA_READONLY) {
@@ -732,7 +772,7 @@ smb_open_subr(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (sr->smb_error.status);
} else {
op->fqi.last_attr = node->attr;
}
@@ -751,7 +791,7 @@ smb_open_subr(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (sr->smb_error.status);
}
node = op->fqi.last_snode;
@@ -777,7 +817,7 @@ smb_open_subr(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (NT_STATUS_ACCESS_DENIED);
}
if (max_requested) {
@@ -806,7 +846,7 @@ smb_open_subr(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
smbsr_error(sr, err.status, err.errcls, err.errcode);
- /* NOTREACHED */
+ return (err.status);
}
/*
@@ -846,7 +886,7 @@ smb_open_subr(struct smb_request *sr)
smbsr_error(sr, status,
ERRDOS, ERROR_SHARING_VIOLATION);
- /* NOTREACHED */
+ return (status);
}
op->my_flags |= granted_oplock;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_search.c b/usr/src/uts/common/fs/smbsrv/smb_common_search.c
index 84d35fe9b0..b5fb122791 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_search.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_search.c
@@ -41,8 +41,7 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
smb_odir_t *od;
smb_node_t *node;
char *last_component;
- unsigned int rc;
- int erc;
+ int rc;
last_component = kmem_alloc(MAXNAMELEN, KM_SLEEP);
@@ -51,28 +50,29 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
&node, last_component)) != 0) {
kmem_free(last_component, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (-1);
}
if ((node->vp)->v_type != VDIR) {
smb_node_release(node);
kmem_free(last_component, MAXNAMELEN);
smbsr_error(sr, 0, ERRDOS, ERRbadpath);
- /* NOTREACHED */
+ return (-1);
}
- erc = smb_fsop_access(sr, sr->user_cr, node, FILE_LIST_DIRECTORY);
- if (erc != 0) {
+ rc = smb_fsop_access(sr, sr->user_cr, node, FILE_LIST_DIRECTORY);
+ if (rc != 0) {
smb_node_release(node);
kmem_free(last_component, MAXNAMELEN);
+
if (sr->smb_com == SMB_COM_SEARCH) {
smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
ERRDOS, ERROR_NO_MORE_FILES);
- return (SDRC_NORMAL_REPLY);
+ return (-2);
} else {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (-1);
}
}
@@ -82,13 +82,12 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
if (od == NULL) {
smb_node_release(node);
smbsr_error(sr, 0, ERRDOS, ERROR_NO_MORE_FILES);
- /* NOTREACHED */
+ return (-1);
}
sr->smb_sid = od->d_sid;
sr->sid_odir = od;
-
- return (-1);
+ return (0);
}
@@ -250,12 +249,10 @@ smb_rdir_next(
dir->d_dir_snode, pc->dc_name, &fnode, &pc->dc_attr, 0, 0);
if (rc != 0) {
- if (rc != ENOENT) {
+ if (rc != ENOENT)
return (rc);
- }
- else
- continue;
- /* NOTREACHED */
+
+ continue;
}
/* Root of file system? */
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
index dff0a689dd..331c785202 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
@@ -56,16 +56,13 @@ extern int smb_maxbufsize;
* be applied to its peer.
*/
-int smb_trans_ready(struct smb_xa *xa);
-int smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa);
-int smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa);
-int smb_trans2_find(struct smb_request *sr, struct smb_xa *xa, int opcode);
-int smb_trans2_query_fs_info(struct smb_request *sr, struct smb_xa *xa);
+static int smb_trans_ready(struct smb_xa *);
+static smb_sdrc_t smb_trans_dispatch(struct smb_request *, struct smb_xa *);
+static smb_sdrc_t smb_trans2_dispatch(struct smb_request *, struct smb_xa *);
+static smb_sdrc_t smb_nt_transact_query_quota(struct smb_request *,
+ struct smb_xa *);
-
-int smb_nt_transact_query_quota(struct smb_request *sr, struct smb_xa *xa);
-
-int
+smb_sdrc_t
smb_com_transaction(struct smb_request *sr)
{
int rc;
@@ -81,16 +78,14 @@ smb_com_transaction(struct smb_request *sr)
&tpscnt, &tdscnt, &mprcnt, &mdrcnt, &msrcnt, &flags,
&timeo, &pscnt, &psoff, &dscnt, &dsoff, &suwcnt);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
msrcnt, suwcnt);
if (xa == NULL) {
smbsr_error(sr, 0, ERRSRV, ERRnoroom);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/* Should be some alignment stuff here in SMB? */
@@ -101,8 +96,7 @@ smb_com_transaction(struct smb_request *sr)
}
if (rc != 0) {
smb_xa_rele(sr->session, xa);
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
xa->xa_smb_trans_name = MEM_STRDUP("smb", stn);
@@ -115,17 +109,17 @@ smb_com_transaction(struct smb_request *sr)
sr->smb_vwv.chain_offset, suwcnt * 2)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
ready = smb_trans_ready(xa);
@@ -133,26 +127,25 @@ smb_com_transaction(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRsrverror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->r_xa = xa;
if (!ready) {
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
return (smb_trans_dispatch(sr, xa));
}
-
-int
+smb_sdrc_t
smb_com_transaction_secondary(struct smb_request *sr)
{
uint16_t tpscnt, tdscnt, pscnt, psdisp;
@@ -162,14 +155,14 @@ smb_com_transaction_secondary(struct smb_request *sr)
if ((xa = smbsr_lookup_xa(sr)) == 0) {
smbsr_error(sr, 0, ERRSRV, ERRsrverror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
}
@@ -180,10 +173,8 @@ smb_com_transaction_secondary(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, SMB_TRANSSHDR_ED_FMT, &tpscnt, &tdscnt,
&pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
mutex_enter(&xa->xa_mutex);
xa->smb_tpscnt = tpscnt; /* might have shrunk */
@@ -195,13 +186,13 @@ smb_com_transaction_secondary(struct smb_request *sr)
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
mutex_exit(&xa->xa_mutex);
@@ -214,8 +205,7 @@ smb_com_transaction_secondary(struct smb_request *sr)
return (smb_trans_dispatch(sr, xa));
}
-
-int
+smb_sdrc_t
smb_com_ioctl(struct smb_request *sr)
{
uint16_t fid, category, function, tpscnt, tdscnt, mprcnt;
@@ -227,23 +217,19 @@ smb_com_ioctl(struct smb_request *sr)
&tpscnt, &tdscnt, &mprcnt, &mdrcnt, &timeout, &pscnt,
&pdoff, &dscnt, &dsoff);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
return (SDRC_UNIMPLEMENTED);
}
-
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_ioctl_secondary(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
}
-
-int
+smb_sdrc_t
smb_com_transaction2(struct smb_request *sr)
{
unsigned char msrcnt, suwcnt;
@@ -258,16 +244,14 @@ smb_com_transaction2(struct smb_request *sr)
&mprcnt, &mdrcnt, &msrcnt, &flags, &timeo, &pscnt, &psoff, &dscnt,
&dsoff, &suwcnt);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
msrcnt, suwcnt);
if (xa == 0) {
smbsr_error(sr, 0, ERRSRV, ERRnoroom);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
xa->smb_flags = flags;
@@ -279,17 +263,17 @@ smb_com_transaction2(struct smb_request *sr)
sr->smb_vwv.chain_offset, suwcnt*2)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
ready = smb_trans_ready(xa);
@@ -297,26 +281,25 @@ smb_com_transaction2(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRsrverror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->r_xa = xa;
if (!ready) {
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
return (smb_trans2_dispatch(sr, xa));
}
-
-int
+smb_sdrc_t
smb_com_transaction2_secondary(struct smb_request *sr)
{
uint16_t tpscnt, tdscnt, fid;
@@ -326,14 +309,14 @@ smb_com_transaction2_secondary(struct smb_request *sr)
if ((xa = smbsr_lookup_xa(sr)) == 0) {
smbsr_error(sr, 0, ERRSRV, ERRsrverror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
}
@@ -344,10 +327,8 @@ smb_com_transaction2_secondary(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, SMB_TRANS2SHDR_ED_FMT, &tpscnt, &tdscnt,
&pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp, &fid);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
mutex_enter(&xa->xa_mutex);
xa->smb_tpscnt = tpscnt; /* might have shrunk */
@@ -360,13 +341,13 @@ smb_com_transaction2_secondary(struct smb_request *sr)
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
mutex_exit(&xa->xa_mutex);
@@ -379,7 +360,7 @@ smb_com_transaction2_secondary(struct smb_request *sr)
return (smb_trans2_dispatch(sr, xa));
}
-static int
+static smb_sdrc_t
smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
{
int rc;
@@ -419,15 +400,15 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case NT_TRANSACT_QUERY_QUOTA:
(void) smb_nt_transact_query_quota(sr, xa);
smbsr_error(sr, 0, ERRSRV, ERRaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
case NT_TRANSACT_SET_QUOTA:
smbsr_error(sr, 0, ERRSRV, ERRaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
default:
smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
switch (rc) {
@@ -442,7 +423,7 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case SDRC_UNIMPLEMENTED:
case SDRC_UNSUPPORTED:
smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
default:
break;
@@ -456,7 +437,7 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
xa->smb_mprcnt < n_param ||
xa->smb_mdrcnt < n_data) {
smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/* neato, blast it over there */
@@ -468,7 +449,7 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
data_off = param_off + n_param + data_pad; /* Param off from hdr */
total_bytes = param_pad + n_param + data_pad + n_data;
- smbsr_encode_result(sr, 18+n_setup, total_bytes,
+ rc = smbsr_encode_result(sr, 18+n_setup, total_bytes,
"b 3. llllllllb C w #. C #. C",
18 + n_setup, /* wct */
n_param, /* Total Parameter Bytes */
@@ -486,35 +467,29 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
&xa->rep_param_mb,
data_pad,
&xa->rep_data_mb);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
* smb_nt_transact_query_quota
*
- * Stub to help debunk this function. There are 16 parameter bytes. The
- * first parameter is definitely the fid. The second looks like a flags
- * field. Then there are 12 bytes (probably 3 dwords) - all zero.
+ * There are 16 parameter bytes: fid, flags and 12 zero bytes.
*/
-int
+static smb_sdrc_t
smb_nt_transact_query_quota(struct smb_request *sr, struct smb_xa *xa)
{
uint16_t fid;
uint16_t flags;
- int rc;
- rc = smb_decode_mbc(&xa->req_param_mb, "%ww", sr, &fid, &flags);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smb_decode_mbc(&xa->req_param_mb, "%ww", sr, &fid, &flags))
+ return (SDRC_ERROR_REPLY);
return (SDRC_NORMAL_REPLY);
}
-int
+smb_sdrc_t
smb_com_nt_transact(struct smb_request *sr)
{
uint16_t Function;
@@ -531,16 +506,14 @@ smb_com_nt_transact(struct smb_request *sr)
&MaxDataCount, &pscnt, &psoff, &dscnt,
&dsoff, &SetupCount, &Function);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
xa = smb_xa_create(sr->session, sr, TotalParameterCount, TotalDataCount,
MaxParameterCount, MaxDataCount, MaxSetupCount, SetupCount);
if (xa == 0) {
smbsr_error(sr, 0, ERRSRV, ERRnoroom);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
xa->smb_flags = 0;
@@ -553,17 +526,17 @@ smb_com_nt_transact(struct smb_request *sr)
sr->smb_vwv.chain_offset, SetupCount * 2)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
ready = smb_trans_ready(xa);
@@ -571,26 +544,26 @@ smb_com_nt_transact(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRsrverror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->r_xa = xa;
if (!ready) {
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
return (smb_nt_trans_dispatch(sr, xa));
}
-int
+smb_sdrc_t
smb_com_nt_transact_secondary(struct smb_request *sr)
{
uint16_t tpscnt, tdscnt, fid;
@@ -600,14 +573,14 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
if ((xa = smbsr_lookup_xa(sr)) == 0) {
smbsr_error(sr, 0, ERRSRV, ERRsrverror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
}
@@ -618,10 +591,8 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, SMB_TRANS2SHDR_ED_FMT, &tpscnt, &tdscnt,
&pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp, &fid);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
mutex_enter(&xa->xa_mutex);
xa->smb_tpscnt = tpscnt; /* might have shrunk */
@@ -634,13 +605,13 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
smbsr_error(sr, 0, ERRDOS, ERRbadformat);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
mutex_exit(&xa->xa_mutex);
@@ -653,7 +624,7 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
return (smb_nt_trans_dispatch(sr, xa));
}
-int
+static int
smb_trans_ready(struct smb_xa *xa)
{
int rc;
@@ -1221,7 +1192,9 @@ smb_trans_net_share_enum(struct smb_request *sr, struct smb_xa *xa)
/* Check buffer to have enough space */
if (shares_tot_byte == 0) {
- return (SDRC_ERROR_REPLY);
+ (void) smb_encode_mbc(&xa->rep_param_mb, "wwww",
+ ERROR_NOT_ENOUGH_MEMORY, 0, 0, 0);
+ return (SDRC_NORMAL_REPLY);
}
max_shares_per_packet = data_buf_limit / SHARE_INFO_1_SIZE;
@@ -1526,8 +1499,7 @@ smb_trans_net_user_get_info(struct smb_request *sr, struct smb_xa *xa)
return (SDRC_NORMAL_REPLY);
}
-
-int
+smb_sdrc_t
smb_trans_server_get_info(struct smb_request *sr, struct smb_xa *xa)
{
uint16_t opcode, level, buf_size;
@@ -1540,8 +1512,7 @@ smb_trans_server_get_info(struct smb_request *sr, struct smb_xa *xa)
if (smb_decode_mbc(&xa->req_param_mb, "%wssww", sr,
&opcode, &req_fmt, &rep_fmt, &level, &buf_size) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
comment = smb_info.si.skc_system_comment;
@@ -1883,7 +1854,7 @@ is_supported_pipe(char *pname)
return (1);
}
-int
+static smb_sdrc_t
smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
{
int rc, pos;
@@ -1928,7 +1899,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_decode_mbc(&xa->req_data_mb, "#B",
@@ -1942,7 +1913,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case TRANS_WAIT_NMPIPE:
if (is_supported_pipe(xa->xa_smb_trans_name) == 0) {
smbsr_error(sr, 0, ERRDOS, ERRbadfile);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = SDRC_NORMAL_REPLY;
break;
@@ -2033,7 +2004,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
data_off = param_off + n_param + data_pad;
total_bytes = param_pad + n_param + data_pad + n_data;
- smbsr_encode_result(sr, 10+n_setup, total_bytes,
+ rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
"b ww 2. www www b . C w #. C #. C",
10 + n_setup, /* wct */
n_param, /* Total Parameter Bytes */
@@ -2051,7 +2022,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
&xa->rep_param_mb,
data_pad,
&xa->rep_data_mb);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
trans_err_too_small:
rc = NERR_BufTooSmall;
@@ -2063,7 +2034,7 @@ trans_err_not_supported:
trans_err:
pos = MBC_LENGTH(&sr->reply) + 23;
- smbsr_encode_result(sr, 10, 4, "b ww 2. www www b . w ww",
+ rc = smbsr_encode_result(sr, 10, 4, "b ww 2. www www b . w ww",
10, /* wct */
4, 0, /* tpscnt tdscnt */
4, pos, 0, /* pscnt psoff psdisp */
@@ -2072,11 +2043,10 @@ trans_err:
4, /* bcc */
rc,
0); /* converter word? */
-
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
-int
+static smb_sdrc_t
smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
{
int rc, pos;
@@ -2121,7 +2091,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (n_data == 0) {
smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_com_trans2_find_first2(sr, xa);
break;
@@ -2134,7 +2104,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (n_data == 0) {
smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_com_trans2_find_next2(sr, xa);
break;
@@ -2147,7 +2117,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (n_data == 0) {
smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_com_trans2_query_fs_information(sr, xa);
break;
@@ -2160,7 +2130,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (n_data == 0) {
smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_com_trans2_query_path_information(sr, xa);
break;
@@ -2173,7 +2143,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (n_data == 0) {
smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_com_trans2_query_file_information(sr, xa);
break;
@@ -2246,7 +2216,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
total_bytes = param_pad + n_param + data_pad + n_data;
- smbsr_encode_result(sr, 10+n_setup, total_bytes,
+ rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
fmt,
10 + n_setup, /* wct */
n_param, /* Total Parameter Bytes */
@@ -2264,7 +2234,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
&xa->rep_param_mb,
nt_unknown_secret,
&xa->rep_data_mb);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
trans_err_too_small:
rc = NERR_BufTooSmall;
@@ -2276,7 +2246,7 @@ trans_err_not_supported:
trans_err:
pos = MBC_LENGTH(&sr->reply) + 23;
- smbsr_encode_result(sr, 10, 4, "b ww 2. www www b . w ww",
+ rc = smbsr_encode_result(sr, 10, 4, "b ww 2. www www b . w ww",
10, /* wct */
4, 0, /* tpscnt tdscnt */
4, pos, 0, /* pscnt psoff psdisp */
@@ -2285,7 +2255,7 @@ trans_err:
4, /* bcc */
rc,
0); /* converter word? */
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
smb_xa_t *
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_tree.c b/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
index 6947474f77..3c6232b61d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
@@ -79,12 +79,12 @@ smbsr_connect_tree(struct smb_request *sr)
*/
if (sharename[1] != '\\') {
smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
- /* NOTREACHED */
+ return (ERRinvnetname);
}
if ((sharename = strchr(sharename+2, '\\')) == 0) {
smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
- /* NOTREACHED */
+ return (ERRinvnetname);
}
++sharename;
@@ -93,13 +93,13 @@ smbsr_connect_tree(struct smb_request *sr)
* This should be a sharename: no embedded '\' allowed.
*/
smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
- /* NOTREACHED */
+ return (ERRinvnetname);
}
if (smb_get_stype(sharename, sr->arg.tcon.service, &stype) != 0) {
smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
ERRDOS, ERROR_BAD_DEV_TYPE);
- /* NOTREACHED */
+ return (ERROR_BAD_DEV_TYPE);
}
if ((rc = smbsr_setup_share(sr, sharename, stype, errmsg)) != 0) {
@@ -112,7 +112,7 @@ smbsr_connect_tree(struct smb_request *sr)
*/
status = (rc == ERRaccess) ? NT_STATUS_ACCESS_DENIED : 0;
smbsr_error(sr, status, ERRSRV, rc);
- /* NOTREACHED */
+ return (rc);
}
if (STYPE_ISDSK(sr->tid_tree->t_res_type)) {
@@ -124,7 +124,7 @@ smbsr_connect_tree(struct smb_request *sr)
smbsr_share_report(sr, sharename, access_msg, errmsg);
}
- return (rc);
+ return (0);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_copy.c b/usr/src/uts/common/fs/smbsrv/smb_copy.c
index 4b33818eab..9d0d34a4f4 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_copy.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_copy.c
@@ -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.
*/
@@ -114,7 +114,7 @@
#include <smbsrv/smb_incl.h>
/*ARGSUSED*/
-int
+smb_sdrc_t
smb_com_copy(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_create.c b/usr/src/uts/common/fs/smbsrv/smb_create.c
index c38bbfd819..c8747bf925 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_create.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_create.c
@@ -36,44 +36,27 @@ static uint32_t smb_common_create(struct smb_request *sr);
* open the file and return a fid. The file is specified using a
* fully qualified name relative to the tree.
*/
-int
+smb_sdrc_t
smb_com_create(struct smb_request *sr)
{
struct open_param *op = &sr->arg.open;
- uint32_t status;
bzero(op, sizeof (sr->arg.open));
- if (smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec) != 0)
+ return (SDRC_ERROR_REPLY);
- if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
op->create_disposition = FILE_OVERWRITE_IF;
- status = smb_common_create(sr);
-
- switch (status) {
- case NT_STATUS_SUCCESS:
- break;
-
- case NT_STATUS_SHARING_VIOLATION:
- smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
- ERRDOS, ERROR_SHARING_VIOLATION);
- /* NOTREACHED */
- break;
-
- default:
- smbsr_error(sr, status, 0, 0);
- /* NOTREACHED */
- break;
- }
- smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0);
+ if (smb_common_create(sr) != NT_STATUS_SUCCESS)
+ return (SDRC_ERROR_REPLY);
+
+ if (smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0))
+ return (SDRC_ERROR_REPLY);
+
return (SDRC_NORMAL_REPLY);
}
@@ -81,44 +64,27 @@ smb_com_create(struct smb_request *sr)
* Create a new file and return a fid. The file is specified using
* a fully qualified name relative to the tree.
*/
-int
+smb_sdrc_t
smb_com_create_new(struct smb_request *sr)
{
struct open_param *op = &sr->arg.open;
- uint32_t status;
bzero(op, sizeof (sr->arg.open));
- if (smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "wl", &op->dattr, &op->utime.tv_sec) != 0)
+ return (SDRC_ERROR_REPLY);
- if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
op->create_disposition = FILE_CREATE;
- status = smb_common_create(sr);
-
- switch (status) {
- case NT_STATUS_SUCCESS:
- break;
-
- case NT_STATUS_SHARING_VIOLATION:
- smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
- ERRDOS, ERROR_SHARING_VIOLATION);
- /* NOTREACHED */
- break;
-
- default:
- smbsr_error(sr, status, 0, 0);
- /* NOTREACHED */
- break;
- }
- smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0);
+ if (smb_common_create(sr) != NT_STATUS_SUCCESS)
+ return (SDRC_ERROR_REPLY);
+
+ if (smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0))
+ return (SDRC_ERROR_REPLY);
+
return (SDRC_NORMAL_REPLY);
}
@@ -127,28 +93,23 @@ smb_com_create_new(struct smb_request *sr)
* Create a unique file in the specified directory relative to the
* current tree. No attributes are specified.
*/
-int
+smb_sdrc_t
smb_com_create_temporary(struct smb_request *sr)
{
static uint16_t tmp_id = 10000;
struct open_param *op = &sr->arg.open;
char name[SMB_CREATE_NAMEBUF_SZ];
char *buf;
- uint32_t status;
uint16_t reserved;
uint16_t bcc;
bzero(op, sizeof (sr->arg.open));
- if (smbsr_decode_vwv(sr, "wl", &reserved, &op->utime.tv_sec) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "wl", &reserved, &op->utime.tv_sec) != 0)
+ return (SDRC_ERROR_REPLY);
- if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
++tmp_id;
bcc = 1; /* null terminator */
@@ -158,25 +119,14 @@ smb_com_create_temporary(struct smb_request *sr)
(void) snprintf(buf, MAXPATHLEN, "%s\\%s", op->fqi.path, name);
op->fqi.path = buf;
op->create_disposition = FILE_CREATE;
- status = smb_common_create(sr);
-
- switch (status) {
- case NT_STATUS_SUCCESS:
- break;
-
- case NT_STATUS_SHARING_VIOLATION:
- smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
- ERRDOS, ERROR_SHARING_VIOLATION);
- /* NOTREACHED */
- break;
-
- default:
- smbsr_error(sr, status, 0, 0);
- /* NOTREACHED */
- break;
- }
- smbsr_encode_result(sr, 1, 0, "bwwbs", 1, sr->smb_fid, bcc, 4, name);
+ if (smb_common_create(sr) != NT_STATUS_SUCCESS)
+ return (SDRC_ERROR_REPLY);
+
+ if (smbsr_encode_result(sr, 1, 0, "bwwbs", 1, sr->smb_fid, bcc, 4,
+ name))
+ return (SDRC_ERROR_REPLY);
+
return (SDRC_NORMAL_REPLY);
}
@@ -200,7 +150,7 @@ smb_common_create(struct smb_request *sr)
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
- /* NOTREACHED */
+ return (NT_STATUS_INVALID_PARAMETER);
}
op->dsize = 0;
@@ -213,7 +163,7 @@ smb_common_create(struct smb_request *sr)
}
}
- status = smb_open_subr(sr);
+ status = smb_common_open(sr);
if (MYF_OPLOCK_TYPE(op->my_flags) == MYF_OPLOCK_NONE) {
sr->smb_flg &=
diff --git a/usr/src/uts/common/fs/smbsrv/smb_create_directory.c b/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
index cb6e3f6e72..797f585181 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
@@ -67,9 +67,6 @@ typedef struct {
} SmbPath;
-extern int smb_common_create_directory(struct smb_request *sr);
-
-
static int smbpath_next(SmbPath* spp);
static SmbPath* smbpath_new(SmbRequest* sr);
@@ -80,21 +77,25 @@ static SmbPath* smbpath_new(SmbRequest* sr);
* It is possible to get a full pathname here and the client expects any
* or all of the components to be created if they don't already exist.
*/
-int
+smb_sdrc_t
smb_com_create_directory(struct smb_request *sr)
{
SmbPath* spp;
DWORD status;
int rc = 0;
- if (smbsr_decode_data(sr, "%S", sr, &sr->arg.dirop.fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERROR_ACCESS_DENIED);
+ return (SDRC_ERROR_REPLY);
}
+ if (smbsr_decode_data(sr, "%S", sr, &sr->arg.dirop.fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
+
if ((status = smb_validate_dirname(sr->arg.dirop.fqi.path)) != 0) {
smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -105,16 +106,20 @@ smb_com_create_directory(struct smb_request *sr)
while (smbpath_next(spp)) {
rc = smb_common_create_directory(sr);
- if (rc != 0 && rc != EEXIST)
+ if (rc != 0 && rc != EEXIST) {
smbsr_errno(sr, rc);
+ return (SDRC_ERROR_REPLY);
+ }
}
/* We should have created one directory successfully! */
- if (rc != 0)
+ if (rc != 0) {
smbsr_errno(sr, rc);
+ return (SDRC_ERROR_REPLY);
+ }
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
@@ -159,12 +164,6 @@ smb_common_create_directory(struct smb_request *sr)
struct smb_node *dnode;
struct smb_node *node;
- if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
- ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
- }
-
sr->arg.dirop.fqi.srch_attr = 0;
rc = smbd_fs_query(sr, &sr->arg.dirop.fqi, FQM_PATH_MUST_NOT_EXIST);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete.c b/usr/src/uts/common/fs/smbsrv/smb_delete.c
index c3a4dad862..94645c05d1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_delete.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_delete.c
@@ -86,7 +86,7 @@ static uint32_t smb_delete_check(smb_request_t *sr, smb_node_t *node,
* ERRSRV/ERRinvid
* ERRSRV/ERRbaduid
*/
-int
+smb_sdrc_t
smb_com_delete(struct smb_request *sr)
{
int rc;
@@ -104,15 +104,14 @@ smb_com_delete(struct smb_request *sr)
int is_stream;
smb_odir_context_t *pc;
- if (smbsr_decode_vwv(sr, "w", &sattr) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "w", &sattr) != 0)
+ return (SDRC_ERROR_REPLY);
- if (smbsr_decode_data(sr, "%S", sr, &path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%S", sr, &path) != 0)
+ return (SDRC_ERROR_REPLY);
+
+ if (smb_rdir_open(sr, path, sattr) != 0)
+ return (SDRC_ERROR_REPLY);
pc = kmem_zalloc(sizeof (*pc), KM_SLEEP);
fname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
@@ -121,8 +120,6 @@ smb_com_delete(struct smb_request *sr)
fullname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
is_stream = smb_stream_parse_name(path, fname, sname);
-
- (void) smb_rdir_open(sr, path, sattr);
dir_snode = sr->sid_odir->d_dir_snode;
/*
@@ -208,31 +205,15 @@ smb_com_delete(struct smb_request *sr)
node = NULL;
if (rc != 0) {
- if (rc != ENOENT) {
- smb_rdir_close(sr);
- kmem_free(pc, sizeof (*pc));
- kmem_free(name, MAXNAMELEN);
- kmem_free(fname, MAXNAMELEN);
- kmem_free(sname, MAXNAMELEN);
- kmem_free(fullname, MAXPATHLEN);
- smbsr_errno(sr, rc);
- /* NOTREACHED */
- }
+ if (rc != ENOENT)
+ goto delete_errno;
} else {
deleted++;
}
}
if ((rc != 0) && (rc != ENOENT)) {
- /* rc returned by smb_rdir_next() */
- smb_rdir_close(sr);
- kmem_free(pc, sizeof (*pc));
- kmem_free(name, MAXNAMELEN);
- kmem_free(fname, MAXNAMELEN);
- kmem_free(sname, MAXNAMELEN);
- kmem_free(fullname, MAXPATHLEN);
- smbsr_errno(sr, rc);
- /* NOTREACHED */
+ goto delete_errno;
}
if (deleted == 0) {
@@ -244,15 +225,24 @@ smb_com_delete(struct smb_request *sr)
}
smb_rdir_close(sr);
+ kmem_free(pc, sizeof (*pc));
+ kmem_free(name, MAXNAMELEN);
+ kmem_free(fname, MAXNAMELEN);
+ kmem_free(sname, MAXNAMELEN);
+ kmem_free(fullname, MAXPATHLEN);
- smbsr_encode_empty_result(sr);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
+delete_errno:
+ smb_rdir_close(sr);
kmem_free(pc, sizeof (*pc));
kmem_free(name, MAXNAMELEN);
kmem_free(fname, MAXNAMELEN);
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
- return (SDRC_NORMAL_REPLY);
+ smbsr_errno(sr, rc);
+ return (SDRC_ERROR_REPLY);
delete_error:
smb_rdir_close(sr);
@@ -262,8 +252,7 @@ delete_error:
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
- /* NOTREACHED */
- return (SDRC_NORMAL_REPLY); /* compiler complains otherwise */
+ return (SDRC_ERROR_REPLY);
}
uint32_t
diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c b/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
index 514551ad97..75c31a35be 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
@@ -56,7 +56,7 @@
* UCHAR WordCount; Count of parameter words = 0
* USHORT ByteCount; Count of data bytes = 0
*/
-int
+smb_sdrc_t
smb_com_delete_directory(struct smb_request *sr)
{
smb_node_t *dnode;
@@ -65,20 +65,18 @@ smb_com_delete_directory(struct smb_request *sr)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- if (smbsr_decode_data(sr, "%S", sr, &sr->arg.dirop.fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%S", sr, &sr->arg.dirop.fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
sr->arg.dirop.fqi.srch_attr = 0;
rc = smbd_fs_query(sr, &sr->arg.dirop.fqi, FQM_PATH_MUST_EXIST);
if (rc) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
dnode = sr->arg.dirop.fqi.last_snode;
@@ -90,7 +88,7 @@ smb_com_delete_directory(struct smb_request *sr)
smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_node_release(dnode);
@@ -103,12 +101,12 @@ smb_com_delete_directory(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_node_release(dnode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
index 0cc54ae43e..e62ddccaf6 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
@@ -149,87 +149,8 @@ static kstat_t *smb_dispatch_ksp = NULL;
static kstat_named_t *smb_dispatch_kstat_data = NULL;
static int smb_dispatch_kstat_size = 0;
-static int is_andx_com(unsigned char);
-
-extern void smbsr_decode_error(struct smb_request *sr);
-extern void smbsr_encode_error(struct smb_request *sr);
-extern void smbsr_check_result(struct smb_request *sr, int wct, int bcc);
-
-extern int smb_com_cancel_forward(struct smb_request *);
-extern int smb_com_check_directory(struct smb_request *);
-extern int smb_com_close(struct smb_request *);
-extern int smb_com_close_and_tree_disconnect(struct smb_request *);
-extern int smb_com_close_print_file(struct smb_request *);
-extern int smb_com_copy(struct smb_request *);
-extern int smb_com_create(struct smb_request *);
-extern int smb_com_create_directory(struct smb_request *);
-extern int smb_com_create_new(struct smb_request *);
-extern int smb_com_create_temporary(struct smb_request *);
-extern int smb_com_delete(struct smb_request *);
-extern int smb_com_delete_directory(struct smb_request *);
-extern int smb_com_echo(struct smb_request *);
-extern int smb_com_find(struct smb_request *);
-extern int smb_com_find_close(struct smb_request *);
-extern int smb_com_find_close2(struct smb_request *);
-extern int smb_com_find_notify_close(struct smb_request *);
-extern int smb_com_find_unique(struct smb_request *);
-extern int smb_com_flush(struct smb_request *);
-extern int smb_com_forward_user_name(struct smb_request *);
-extern int smb_com_get_machine_name(struct smb_request *);
-extern int smb_com_get_print_queue(struct smb_request *);
-extern int smb_com_invalid_command(struct smb_request *);
-extern int smb_com_ioctl(struct smb_request *);
-extern int smb_com_ioctl_secondary(struct smb_request *);
-extern int smb_com_lock_and_read(struct smb_request *);
-extern int smb_com_lock_byte_range(struct smb_request *);
-extern int smb_com_locking_andx(struct smb_request *);
-extern int smb_com_logoff_andx(struct smb_request *);
-extern int smb_com_move(struct smb_request *);
-extern int smb_com_negotiate(struct smb_request *);
-extern int smb_com_nt_cancel(struct smb_request *);
-extern int smb_com_nt_create_andx(struct smb_request *);
-extern int smb_com_nt_transact(struct smb_request *);
-extern int smb_com_nt_transact_secondary(struct smb_request *);
-extern int smb_com_open(struct smb_request *);
-extern int smb_com_open_andx(struct smb_request *);
-extern int smb_com_open_print_file(struct smb_request *);
-extern int smb_com_process_exit(struct smb_request *);
-extern int smb_com_query_information(struct smb_request *);
-extern int smb_com_query_information2(struct smb_request *);
-extern int smb_com_query_information_disk(struct smb_request *);
-extern int smb_com_read(struct smb_request *);
-extern int smb_com_read_andx(struct smb_request *);
-extern int smb_com_read_mpx(struct smb_request *);
-extern int smb_com_read_mpx_secondary(struct smb_request *);
-extern int smb_com_read_raw(struct smb_request *);
-extern int smb_com_rename(struct smb_request *);
-extern int smb_com_search(struct smb_request *);
-extern int smb_com_seek(struct smb_request *);
-extern int smb_com_send_broadcast_message(struct smb_request *);
-extern int smb_com_send_end_mb_message(struct smb_request *);
-extern int smb_com_send_single_message(struct smb_request *);
-extern int smb_com_send_start_mb_message(struct smb_request *);
-extern int smb_com_send_text_mb_message(struct smb_request *);
-extern int smb_com_session_setup_andx(struct smb_request *);
-extern int smb_com_set_information(struct smb_request *);
-extern int smb_com_set_information2(struct smb_request *);
-extern int smb_com_transaction(struct smb_request *);
-extern int smb_com_transaction2(struct smb_request *);
-extern int smb_com_transaction2_secondary(struct smb_request *);
-extern int smb_com_transaction_secondary(struct smb_request *);
-extern int smb_com_tree_connect(struct smb_request *);
-extern int smb_com_tree_connect_andx(struct smb_request *);
-extern int smb_com_tree_disconnect(struct smb_request *);
-extern int smb_com_unlock_byte_range(struct smb_request *);
-extern int smb_com_write(struct smb_request *);
-extern int smb_com_write_and_close(struct smb_request *);
-extern int smb_com_write_and_unlock(struct smb_request *);
-extern int smb_com_write_andx(struct smb_request *);
-extern int smb_com_write_complete(struct smb_request *);
-extern int smb_com_write_mpx(struct smb_request *);
-extern int smb_com_write_mpx_secondary(struct smb_request *);
-extern int smb_com_write_print_file(struct smb_request *);
-extern int smb_com_write_raw(struct smb_request *);
+static int is_andx_com(unsigned char);
+static int smbsr_check_result(struct smb_request *, int, int);
static smb_dispatch_table_t dispatch[256] = {
{ smb_com_create_directory, /* 0x00 000 */
@@ -715,8 +636,6 @@ static smb_dispatch_table_t dispatch[256] = {
{ 0, 0, 0, RW_READER, 0 } /* 0xFF 255 */
};
-int smb_watch = -1;
-int smb_emit_sending = 0;
/*
* smbsr_cleanup
@@ -767,12 +686,12 @@ smbsr_cleanup(struct smb_request *sr)
mutex_exit(&sr->sr_mutex);
}
-int
+void
smb_dispatch_request(struct smb_request *sr)
{
- int rc;
+ smb_sdrc_t sdrc;
smb_dispatch_table_t *sdd;
- smb_error_t err;
+ boolean_t disconnect = B_FALSE;
ASSERT(sr->tid_tree == 0);
ASSERT(sr->uid_user == 0);
@@ -799,15 +718,16 @@ smb_dispatch_request(struct smb_request *sr)
&sr->smb_pid,
&sr->smb_uid,
&sr->smb_mid) != 0) {
- return (-1);
+ disconnect = B_TRUE;
+ goto drop_connection;
}
/*
- * The reply "header" is filled in now even though
- * it most likely will be rewritten under reply_ready:
- * below. Could just reserve the space. But this
- * (for now) is convenient incase the dialect dispatcher
- * has to send a special reply (like TRANSACT).
+ * The reply "header" is filled in now even though it will,
+ * most likely, be rewritten under reply_ready below. We
+ * could reserve the space but this is convenient in case
+ * the dialect dispatcher has to send a special reply (like
+ * TRANSACT).
*
* Ensure that the 32-bit error code flag is turned off.
* Clients seem to set it in transact requests and they may
@@ -839,14 +759,11 @@ smb_dispatch_request(struct smb_request *sr)
*/
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_request(sr) != 0) {
- err.severity = ERROR_SEVERITY_ERROR;
- err.status = NT_STATUS_ACCESS_DENIED;
- err.errcls = ERRDOS;
- err.errcode = ERROR_ACCESS_DENIED;
- smbsr_set_error(sr, &err);
- rc = -1;
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERROR_ACCESS_DENIED);
+ disconnect = B_TRUE;
smb_rwx_rwenter(&sr->session->s_lock, RW_READER);
- goto reply_error;
+ goto report_error;
}
}
@@ -856,17 +773,16 @@ andx_more:
smb_rwx_rwenter(&sr->session->s_lock, sdd->sdt_slock_mode);
if (smb_decode_mbc(&sr->command, "b", &sr->smb_wct) != 0) {
- rc = -3;
- goto cant_decode;
+ disconnect = B_TRUE;
+ goto report_error;
}
(void) MBC_SHADOW_CHAIN(&sr->smb_vwv, &sr->command,
sr->command.chain_offset, sr->smb_wct * 2);
- if (smb_decode_mbc(&sr->command, "#.w",
- sr->smb_wct*2, &sr->smb_bcc) != 0) {
- rc = -5;
- goto cant_decode;
+ if (smb_decode_mbc(&sr->command, "#.w", sr->smb_wct*2, &sr->smb_bcc)) {
+ disconnect = B_TRUE;
+ goto report_error;
}
(void) MBC_SHADOW_CHAIN(&sr->smb_data, &sr->command,
@@ -874,8 +790,8 @@ andx_more:
sr->command.chain_offset += sr->smb_bcc;
if (sr->command.chain_offset > sr->command.max_bytes) {
- rc = -6;
- goto cant_decode;
+ disconnect = B_TRUE;
+ goto report_error;
}
/* Store pointers for later */
@@ -885,8 +801,8 @@ andx_more:
/* Peek ahead and don't disturb vwv */
if (smb_peek_mbc(&sr->smb_vwv, sr->smb_vwv.chain_offset, "b.w",
&sr->andx_com, &sr->andx_off) < 0) {
- rc = -7;
- goto cant_decode;
+ disconnect = B_TRUE;
+ goto report_error;
}
} else {
sr->andx_com = (unsigned char)-1;
@@ -906,227 +822,178 @@ andx_more:
}
mutex_exit(&sr->sr_mutex);
- if (sdd->sdt_function) {
-
- if ((rc = setjmp(&sr->exjb))) {
- /*
- * Handle any errors from raw write.
- */
- if (sr->session->s_state ==
- SMB_SESSION_STATE_WRITE_RAW_ACTIVE) {
- /*
- * Set state so that the netbios session
- * daemon will start accepting data again.
- */
- sr->session->s_write_raw_status = 0;
- sr->session->s_state =
- SMB_SESSION_STATE_NEGOTIATED;
- }
-
- /*
- * We should never have sr->sr_keep set here
- * since this is the error path.
- */
- ASSERT(sr->sr_keep == 0);
-
- smbsr_cleanup(sr);
+ if (sdd->sdt_function == NULL) {
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
+ goto report_error;
+ }
- if (sr->smb_com == smb_watch) {
- smb_emit_sending = 1;
- }
- if (rc < 0) {
- rc -= 1000;
- goto cant_decode;
- }
- goto reply_error;
+ /*
+ * Setup UID and TID information (if required). Both functions
+ * will set the sr credentials. In domain mode, the user and
+ * tree credentials should be the same. In share mode, the
+ * tree credentials (defined in the share definition) should
+ * override the user credentials.
+ */
+ if (!(sdd->sdt_flags & SDDF_SUPPRESS_UID)) {
+ sr->uid_user = smb_user_lookup_by_uid(sr->session,
+ &sr->user_cr, sr->smb_uid);
+ if (sr->uid_user == NULL) {
+ smbsr_error(sr, 0, ERRSRV, ERRbaduid);
+ goto report_error;
}
- /*
- * Setup UID and TID information (if required). Both functions
- * will set the sr credentials. In domain mode, the user and
- * tree credentials should be the same. In share mode, the
- * tree credentials (defined in the share definition) should
- * override the user credentials.
- */
- if (!(sdd->sdt_flags & SDDF_SUPPRESS_UID)) {
- sr->uid_user = smb_user_lookup_by_uid(sr->session,
- &sr->user_cr, sr->smb_uid);
- if (sr->uid_user == NULL) {
- smbsr_error(sr, 0, ERRSRV, ERRbaduid);
- /* NOTREACHED */
- }
- if (!(sdd->sdt_flags & SDDF_SUPPRESS_TID)) {
- sr->tid_tree = smb_tree_lookup_by_tid(
- sr->uid_user, sr->smb_tid);
- if (sr->tid_tree == NULL) {
- smbsr_error(sr, 0, ERRSRV, ERRinvnid);
- /* NOTREACHED */
- }
+ if (!(sdd->sdt_flags & SDDF_SUPPRESS_TID)) {
+ sr->tid_tree = smb_tree_lookup_by_tid(
+ sr->uid_user, sr->smb_tid);
+ if (sr->tid_tree == NULL) {
+ smbsr_error(sr, 0, ERRSRV, ERRinvnid);
+ goto report_error;
}
}
+ }
+ /*
+ * If the command is not a read raw request we can set the
+ * state of the session back to SMB_SESSION_STATE_NEGOTIATED
+ * (if the current state is SMB_SESSION_STATE_OPLOCK_BREAKING).
+ * Otherwise we let the read raw handler to deal with it.
+ */
+ if ((sr->session->s_state == SMB_SESSION_STATE_OPLOCK_BREAKING) &&
+ (sr->smb_com != SMB_COM_READ_RAW)) {
+ krw_t mode;
/*
- * If the command is not a read raw request we can set the
- * state of the session back to SMB_SESSION_STATE_NEGOTIATED
- * (if the current state is SMB_SESSION_STATE_OPLOCK_BREAKING).
- * Otherwise we let the read raw handler to deal with it.
+ * The lock may have to be upgraded because, at this
+ * point, we don't know how it was entered. We just
+ * know that it has to be entered in writer mode here.
+ * Whatever mode was used to enter the lock, it will
+ * be restored.
*/
- if ((sr->session->s_state ==
- SMB_SESSION_STATE_OPLOCK_BREAKING) &&
- (sr->smb_com != SMB_COM_READ_RAW)) {
- krw_t mode;
- /*
- * The lock may have to be upgraded because, at this
- * point, we don't know how it was entered. We just
- * know that it has to be entered in writer mode here.
- * Whatever mode was used to enter the lock, it will
- * be restored.
- */
- mode = smb_rwx_rwupgrade(&sr->session->s_lock);
- if (sr->session->s_state ==
- SMB_SESSION_STATE_OPLOCK_BREAKING) {
- sr->session->s_state =
- SMB_SESSION_STATE_NEGOTIATED;
- }
- smb_rwx_rwdowngrade(&sr->session->s_lock, mode);
- }
+ mode = smb_rwx_rwupgrade(&sr->session->s_lock);
+ if (sr->session->s_state == SMB_SESSION_STATE_OPLOCK_BREAKING)
+ sr->session->s_state = SMB_SESSION_STATE_NEGOTIATED;
- DTRACE_PROBE1(smb__dispatch__com, struct smb_request_t *, sr);
+ smb_rwx_rwdowngrade(&sr->session->s_lock, mode);
+ }
- /*
- * Increment method invocation count. This value is exposed
- * via kstats, and it represents a count of all the dispatched
- * requests, including the ones that have a return value, other
- * than SDRC_NORMAL_REPLY.
- */
- SMB_ALL_DISPATCH_STAT_INCR(sdd->sdt_dispatch_stats.value.ui64);
+ DTRACE_PROBE1(smb__dispatch__com, struct smb_request_t *, sr);
- rc = (*sdd->sdt_function)(sr);
+ /*
+ * Increment method invocation count. This value is exposed
+ * via kstats, and it represents a count of all the dispatched
+ * requests, including the ones that have a return value, other
+ * than SDRC_NORMAL_REPLY.
+ */
+ SMB_ALL_DISPATCH_STAT_INCR(sdd->sdt_dispatch_stats.value.ui64);
+ if ((sdrc = (*sdd->sdt_function)(sr)) != SDRC_NORMAL_REPLY) {
/*
- * Only call smbsr_cleanup if smb->sr_keep is not set. The
- * smb_nt_transact_notify_change function will set
- * smb->sr_keep if it retains control of the request when
- * it returns. In that case the notify change code
- * will call smbsr_cleanup later when the request is finally
- * completed.
+ * Handle errors from raw write.
*/
- if (sr->sr_keep == 0)
- smbsr_cleanup(sr);
- } else {
- rc = SDRC_UNIMPLEMENTED; /* Unknown? */
+ if (sr->session->s_state ==
+ SMB_SESSION_STATE_WRITE_RAW_ACTIVE) {
+ /*
+ * Set state so that the netbios session
+ * daemon will start accepting data again.
+ */
+ sr->session->s_write_raw_status = 0;
+ sr->session->s_state = SMB_SESSION_STATE_NEGOTIATED;
+ }
}
- if (rc != SDRC_NORMAL_REPLY) { /* normal case special & fast */
- switch (rc) {
- case SDRC_NORMAL_REPLY:
- break;
+ /*
+ * Only call smbsr_cleanup if smb->sr_keep is not set.
+ * smb_nt_transact_notify_change will set smb->sr_keep if it
+ * retains control of the request when it returns. In that
+ * case the notify change code will call smbsr_cleanup later
+ * when the request has completed.
+ */
+ if (sr->sr_keep == 0)
+ smbsr_cleanup(sr);
- case SDRC_ERROR_REPLY:
- goto reply_error;
-
- case SDRC_DROP_VC:
- switch (sr->session->s_state) {
- case SMB_SESSION_STATE_DISCONNECTED:
- case SMB_SESSION_STATE_TERMINATED:
- break;
- default:
- smb_soshutdown(sr->session->sock);
- break;
- }
- goto reply_error;
+ switch (sdrc) {
+ case SDRC_NORMAL_REPLY:
+ break;
- case SDRC_NO_REPLY:
- /* tricky. */
- smb_rwx_rwexit(&sr->session->s_lock);
- return (0);
+ case SDRC_DROP_VC:
+ disconnect = B_TRUE;
+ goto drop_connection;
- case SDRC_UNIMPLEMENTED:
- sr->smb_rcls = ERRDOS;
- sr->smb_err = ERRbadfunc;
- goto reply_error;
+ case SDRC_NO_REPLY:
+ smb_rwx_rwexit(&sr->session->s_lock);
+ return;
- default:
- sr->smb_rcls = ERRDOS;
- sr->smb_err = ERRerror; /* need better */
- goto reply_error;
- }
+ case SDRC_ERROR_REPLY:
+ goto report_error;
+
+ case SDRC_UNIMPLEMENTED:
+ case SDRC_UNSUPPORTED:
+ default:
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
+ goto report_error;
}
+ /*
+ * If there's no AndX command, we're done.
+ */
if (sr->andx_com == 0xff)
goto reply_ready;
- /* have to back-patch the AndXCommand and AndXOffset */
+ /*
+ * Otherwise, we have to back-patch the AndXCommand and AndXOffset
+ * and continue processing.
+ */
sr->andx_prev_wct = sr->cur_reply_offset;
(void) smb_poke_mbc(&sr->reply, sr->andx_prev_wct + 1, "b.w",
sr->andx_com, MBC_LENGTH(&sr->reply));
smb_rwx_rwexit(&sr->session->s_lock);
- /* now it gets interesting */
sr->command.chain_offset = sr->orig_request_hdr + sr->andx_off;
-
sr->smb_com = sr->andx_com;
-
goto andx_more;
-reply_ready:
-
- if (SMB_TREE_CASE_INSENSITIVE(sr)) {
- sr->smb_flg |= SMB_FLAGS_CASE_INSENSITIVE;
- } else {
- sr->smb_flg &= ~SMB_FLAGS_CASE_INSENSITIVE;
- }
-
- (void) smb_poke_mbc(&sr->reply, 0, SMB_HEADER_ED_FMT,
- sr->first_smb_com,
- sr->smb_rcls,
- sr->smb_reh,
- sr->smb_err,
- sr->smb_flg | SMB_FLAGS_REPLY,
- sr->smb_flg2,
- sr->smb_pid_high,
- sr->smb_sig,
- sr->smb_tid,
- sr->smb_pid,
- sr->smb_uid,
- sr->smb_mid);
-
- if (sr->session->signing.flags & SMB_SIGNING_ENABLED)
- smb_sign_reply(sr, NULL);
-
- if ((rc = smb_session_send(sr->session, 0, &sr->reply)) == 0)
- sr->reply.chain = 0;
-
- smb_rwx_rwexit(&sr->session->s_lock);
-
- return (rc);
-
-cant_decode:
-reply_error:
+report_error:
sr->reply.chain_offset = sr->cur_reply_offset;
(void) smb_encode_mbc(&sr->reply, "bw", 0, 0);
sr->smb_wct = 0;
sr->smb_bcc = 0;
- if (sr->smb_rcls == 0) {
- sr->smb_rcls = ERRSRV;
- sr->smb_err = ERRerror;
+ if (sr->smb_rcls == 0)
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
+
+reply_ready:
+ smbsr_send_reply(sr);
+
+drop_connection:
+ if (disconnect) {
+ switch (sr->session->s_state) {
+ case SMB_SESSION_STATE_DISCONNECTED:
+ case SMB_SESSION_STATE_TERMINATED:
+ break;
+ default:
+ smb_soshutdown(sr->session->sock);
+ sr->session->s_state = SMB_SESSION_STATE_DISCONNECTED;
+ break;
+ }
}
- goto reply_ready;
+
+ smb_rwx_rwexit(&sr->session->s_lock);
}
+int
+smbsr_encode_empty_result(struct smb_request *sr)
+{
+ return (smbsr_encode_result(sr, 0, 0, "bw", 0, 0));
+}
-void
-smbsr_encode_result(struct smb_request *sr, int wct,
- int bcc, char *fmt, ...)
+int
+smbsr_encode_result(struct smb_request *sr, int wct, int bcc, char *fmt, ...)
{
va_list ap;
- if (MBC_LENGTH(&sr->reply) != sr->cur_reply_offset) {
- smbsr_encode_error(sr);
- }
+ if (MBC_LENGTH(&sr->reply) != sr->cur_reply_offset)
+ return (-1);
va_start(ap, fmt);
(void) smb_mbc_encode(&sr->reply, fmt, ap);
@@ -1135,10 +1002,13 @@ smbsr_encode_result(struct smb_request *sr, int wct,
sr->smb_wct = (unsigned char)wct;
sr->smb_bcc = (uint16_t)bcc;
- smbsr_check_result(sr, wct, bcc);
+ if (smbsr_check_result(sr, wct, bcc) != 0)
+ return (-1);
+
+ return (0);
}
-void
+static int
smbsr_check_result(struct smb_request *sr, int wct, int bcc)
{
int offset = sr->cur_reply_offset;
@@ -1153,53 +1023,44 @@ smbsr_check_result(struct smb_request *sr, int wct, int bcc)
m = m->m_next;
}
- if ((offset + 3) > total_bytes) {
- smbsr_encode_error(sr);
- /* NOTREACHED */
- }
+ if ((offset + 3) > total_bytes)
+ return (-1);
(void) smb_peek_mbc(&sr->reply, offset, "b", &temp);
- if (temp != wct) {
- smbsr_encode_error(sr);
- /* NOTREACHED */
- }
+ if (temp != wct)
+ return (-1);
- if ((offset + (wct * 2 + 1)) > total_bytes) {
- smbsr_encode_error(sr);
- /* NOTREACHED */
- }
+ if ((offset + (wct * 2 + 1)) > total_bytes)
+ return (-1);
/* reply wct & vwv seem ok, consider data now */
offset += wct * 2 + 1;
- if ((offset + 2) > total_bytes) {
- smbsr_encode_error(sr);
- }
+ if ((offset + 2) > total_bytes)
+ return (-1);
(void) smb_peek_mbc(&sr->reply, offset, "bb", &temp, &temp1);
if (bcc == VAR_BCC) {
if ((temp != 0xFF) || (temp1 != 0xFF)) {
- smbsr_encode_error(sr);
- /* NOTREACHED */
+ return (-1);
} else {
bcc = (total_bytes - offset) - 2;
(void) smb_poke_mbc(&sr->reply, offset, "bb",
bcc, bcc >> 8);
}
} else {
- if ((temp != (bcc&0xFF)) || (temp1 != ((bcc>>8)&0xFF))) {
- smbsr_encode_error(sr);
- }
+ if ((temp != (bcc&0xFF)) || (temp1 != ((bcc>>8)&0xFF)))
+ return (-1);
}
offset += bcc + 2;
- if (offset != total_bytes) {
- smbsr_encode_error(sr);
- }
+ if (offset != total_bytes)
+ return (-1);
sr->smb_wct = (unsigned char)wct;
sr->smb_bcc = (uint16_t)bcc;
+ return (0);
}
int
@@ -1229,6 +1090,11 @@ smbsr_decode_data(struct smb_request *sr, char *fmt, ...)
void
smbsr_send_reply(struct smb_request *sr)
{
+ if (SMB_TREE_CASE_INSENSITIVE(sr))
+ sr->smb_flg |= SMB_FLAGS_CASE_INSENSITIVE;
+ else
+ sr->smb_flg &= ~SMB_FLAGS_CASE_INSENSITIVE;
+
(void) smb_poke_mbc(&sr->reply, 0, SMB_HEADER_ED_FMT,
sr->first_smb_com,
sr->smb_rcls,
@@ -1246,26 +1112,8 @@ smbsr_send_reply(struct smb_request *sr)
if (sr->session->signing.flags & SMB_SIGNING_ENABLED)
smb_sign_reply(sr, NULL);
- (void) smb_session_send(sr->session, 0, &sr->reply);
-}
-
-
-void
-smbsr_decode_error(struct smb_request *sr)
-{
- longjmp(&sr->exjb);
-}
-
-void
-smbsr_encode_error(struct smb_request *sr)
-{
- longjmp(&sr->exjb);
-}
-
-void
-smbsr_encode_empty_result(struct smb_request *sr)
-{
- smbsr_encode_result(sr, 0, 0, "bw", 0, 0);
+ if (smb_session_send(sr->session, 0, &sr->reply) == 0)
+ sr->reply.chain = 0;
}
/*
@@ -1330,12 +1178,8 @@ smbsr_map_errno(int errnum, smb_error_t *err)
void
smbsr_errno(struct smb_request *sr, int errnum)
{
- smb_error_t err;
-
- smbsr_map_errno(errnum, &err);
- smbsr_set_error(sr, &err);
- longjmp(&sr->exjb);
- /* NOTREACHED */
+ smbsr_map_errno(errnum, &sr->smb_error);
+ smbsr_set_error(sr, &sr->smb_error);
}
/*
@@ -1344,14 +1188,12 @@ smbsr_errno(struct smb_request *sr, int errnum)
void
smbsr_warn(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode)
{
- smb_error_t err;
-
- err.severity = ERROR_SEVERITY_WARNING;
- err.status = status;
- err.errcls = errcls;
- err.errcode = errcode;
+ sr->smb_error.severity = ERROR_SEVERITY_WARNING;
+ sr->smb_error.status = status;
+ sr->smb_error.errcls = errcls;
+ sr->smb_error.errcode = errcode;
- smbsr_set_error(sr, &err);
+ smbsr_set_error(sr, &sr->smb_error);
}
/*
@@ -1360,16 +1202,12 @@ smbsr_warn(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode)
void
smbsr_error(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode)
{
- smb_error_t err;
+ sr->smb_error.severity = ERROR_SEVERITY_ERROR;
+ sr->smb_error.status = status;
+ sr->smb_error.errcls = errcls;
+ sr->smb_error.errcode = errcode;
- err.severity = ERROR_SEVERITY_ERROR;
- err.status = status;
- err.errcls = errcls;
- err.errcode = errcode;
-
- smbsr_set_error(sr, &err);
- longjmp(&sr->exjb);
- /* NOTREACHED */
+ smbsr_set_error(sr, &sr->smb_error);
}
/*
@@ -1466,7 +1304,7 @@ is_andx_com(unsigned char com)
* Invalid command stub.
*/
/*ARGSUSED*/
-int
+smb_sdrc_t
smb_com_invalid_command(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_echo.c b/usr/src/uts/common/fs/smbsrv/smb_echo.c
index 8a386c9959..becab9b87e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_echo.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_echo.c
@@ -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.
*/
@@ -36,7 +36,7 @@
* Each response echoes the data sent, though ByteCount may indicate
* no data. If echo-count is zero, no response is sent.
*/
-int
+smb_sdrc_t
smb_com_echo(struct smb_request *sr)
{
unsigned short necho;
@@ -45,19 +45,16 @@ smb_com_echo(struct smb_request *sr)
struct mbuf_chain reply;
char *data;
- if (smbsr_decode_vwv(sr, "w", &necho) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "w", &necho) != 0)
+ return (SDRC_ERROR_REPLY);
nbytes = sr->smb_bcc;
-
data = smbsr_malloc(&sr->request_storage, nbytes);
- (void) smb_decode_mbc(&sr->smb_data, "#c", nbytes, data);
+ if (smb_decode_mbc(&sr->smb_data, "#c", nbytes, data))
+ return (SDRC_ERROR_REPLY);
for (i = 1; i <= necho; ++i) {
-
MBC_INIT(&reply, SMB_HEADER_ED_LEN + 10 + nbytes);
(void) smb_encode_mbc(&reply, SMB_HEADER_ED_FMT,
@@ -89,7 +86,7 @@ smb_com_echo(struct smb_request *sr)
/*
* Broadcast messages are not supported.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_send_broadcast_message(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -98,7 +95,7 @@ smb_com_send_broadcast_message(struct smb_request *sr)
/*
* Multi-block messages are not supported.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_send_end_mb_message(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -107,7 +104,7 @@ smb_com_send_end_mb_message(struct smb_request *sr)
/*
* Single-block messages are not supported.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_send_single_message(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -116,7 +113,7 @@ smb_com_send_single_message(struct smb_request *sr)
/*
* Multi-block messages are not supported.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_send_start_mb_message(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -125,7 +122,7 @@ smb_com_send_start_mb_message(struct smb_request *sr)
/*
* Multi-block messages are not supported.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_send_text_mb_message(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_find.c b/usr/src/uts/common/fs/smbsrv/smb_find.c
index a45e5cab64..eac82b3349 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_find.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_find.c
@@ -209,7 +209,7 @@
* ERRSRV/ERRaccess
* ERRSRV/ERRinvnid
*/
-int
+smb_sdrc_t
smb_com_find(struct smb_request *sr)
{
int rc;
@@ -222,27 +222,23 @@ smb_com_find(struct smb_request *sr)
unsigned short key_len;
smb_odir_context_t *pc;
- if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
+ return (SDRC_ERROR_REPLY);
- if ((smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len) != 0) ||
- (type != 0x05)) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ rc = smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len);
+ if ((rc != 0) || (type != 0x05))
+ return (SDRC_ERROR_REPLY);
if (key_len == 0) { /* begin search */
- (void) smb_rdir_open(sr, path, sattr);
+ if (smb_rdir_open(sr, path, sattr) != 0)
+ return (SDRC_ERROR_REPLY);
cookie = 0;
} else if (key_len == 21) {
sr->smb_sid = 0;
if (smb_decode_mbc(&sr->smb_data, SMB_RESUME_KEY_FMT,
filename, &sr->smb_sid, &cookie) != 0) {
/* We don't know which rdir to close */
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
@@ -250,14 +246,13 @@ smb_com_find(struct smb_request *sr)
if (sr->sid_odir == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
cookie--; /* +1 when returned */
} else {
/* We don't know which rdir to close */
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
(void) smb_encode_mbc(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
@@ -287,21 +282,20 @@ smb_com_find(struct smb_request *sr)
/* returned error by smb_rdir_next() */
smb_rdir_close(sr);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (count == 0) {
smb_rdir_close(sr);
smbsr_error(sr, 0, ERRDOS, ERRnofiles);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
- if (smb_poke_mbc(&sr->reply, sr->cur_reply_offset,
- "bwwbw", 1, count, rc+3, 5, rc) < 0) {
+ if (smb_poke_mbc(&sr->reply, sr->cur_reply_offset, "bwwbw",
+ 1, count, rc+3, 5, rc) < 0) {
smb_rdir_close(sr);
- smbsr_encode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
return (SDRC_NORMAL_REPLY);
@@ -385,7 +379,7 @@ smb_com_find(struct smb_request *sr)
* ERRSRV/ERRerror
* ERRSRV/ERRinvnid
*/
-int
+smb_sdrc_t
smb_com_find_close(struct smb_request *sr)
{
unsigned short sattr, maxcount;
@@ -396,28 +390,23 @@ smb_com_find_close(struct smb_request *sr)
unsigned short key_len;
int rc;
- if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
+ return (SDRC_ERROR_REPLY);
rc = smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len);
- if ((rc != 0) || (type != 0x05)) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if ((rc != 0) || (type != 0x05))
+ return (SDRC_ERROR_REPLY);
if (key_len == 0) { /* begin search */
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (key_len == 21) {
sr->smb_sid = 0;
if (smb_decode_mbc(&sr->smb_data, SMB_RESUME_KEY_FMT,
filename, &sr->smb_sid, &cookie) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
@@ -425,16 +414,16 @@ smb_com_find_close(struct smb_request *sr)
if (sr->sid_odir == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
cookie--; /* +1 when returned */
} else {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_rdir_close(sr);
- smbsr_encode_result(sr, 1, 3, "bwwbw", 1, 0, 3, 5, 0);
+ if (smbsr_encode_result(sr, 1, 3, "bwwbw", 1, 0, 3, 5, 0))
+ return (SDRC_ERROR_REPLY);
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_find_notify_close.c b/usr/src/uts/common/fs/smbsrv/smb_find_notify_close.c
index 46a9953b55..0c3c4a6462 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_find_notify_close.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_find_notify_close.c
@@ -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.
*/
@@ -71,7 +71,7 @@
* As far as I can tell, this part of the protocol is not implemented
* by NT server.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_find_notify_close(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_find_unique.c b/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
index f9686297f0..adb3e93dd6 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
@@ -204,7 +204,7 @@
* ERRSRV/ERRaccess
* ERRSRV/ERRinvnid
*/
-int
+smb_sdrc_t
smb_com_find_unique(struct smb_request *sr)
{
int rc;
@@ -217,26 +217,26 @@ smb_com_find_unique(struct smb_request *sr)
vdb = kmem_alloc(sizeof (struct vardata_block), KM_SLEEP);
if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0) {
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (smbsr_decode_data(sr, "%AV", sr, &path, vdb) != 0) {
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (vdb->len != 0) {
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
(void) smb_encode_mbc(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
/* begin search */
- (void) smb_rdir_open(sr, path, sattr);
+ if (smb_rdir_open(sr, path, sattr) != 0) {
+ kmem_free(vdb, sizeof (struct vardata_block));
+ return (SDRC_ERROR_REPLY);
+ }
pc = kmem_zalloc(sizeof (*pc), KM_SLEEP);
pc->dc_cookie = 0;
@@ -265,21 +265,20 @@ smb_com_find_unique(struct smb_request *sr)
/* returned error by smb_rdir_next() */
kmem_free(vdb, sizeof (struct vardata_block));
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (count == 0) {
kmem_free(vdb, sizeof (struct vardata_block));
smbsr_error(sr, 0, ERRDOS, ERRnofiles);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
if (smb_poke_mbc(&sr->reply, sr->cur_reply_offset,
"bwwbw", 1, count, rc+3, 5, rc) < 0) {
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_encode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
kmem_free(vdb, sizeof (struct vardata_block));
return (SDRC_NORMAL_REPLY);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_flush.c b/usr/src/uts/common/fs/smbsrv/smb_flush.c
index c3da4a2352..303c0d5335 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_flush.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_flush.c
@@ -73,20 +73,19 @@ smb_commit_required(int state)
* We need to protect the list because there's a good chance we'll
* block during the flush operation.
*/
-int
+smb_sdrc_t
smb_com_flush(smb_request_t *sr)
{
smb_ofile_t *file;
smb_llist_t *flist;
+ int rc;
- if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0)
+ return (SDRC_ERROR_REPLY);
if (smb_flush_required == 0) {
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
if (sr->smb_fid != 0xffff) {
@@ -95,7 +94,7 @@ smb_com_flush(smb_request_t *sr)
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_flush_file(sr, sr->fid_ofile);
@@ -111,8 +110,9 @@ smb_com_flush(smb_request_t *sr)
}
smb_llist_exit(flist);
}
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
@@ -122,7 +122,8 @@ smb_com_flush(smb_request_t *sr)
* If writes on this file are not synchronous, flush it using the NFSv3
* commit interface.
*/
-static void smb_flush_file(struct smb_request *sr, struct smb_ofile *ofile)
+static void
+smb_flush_file(struct smb_request *sr, struct smb_ofile *ofile)
{
if ((ofile->f_node->flags & NODE_FLAGS_WRITE_THROUGH) == 0)
(void) smb_fsop_commit(sr, sr->user_cr, ofile->f_node);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_forward.c b/usr/src/uts/common/fs/smbsrv/smb_forward.c
index 498e3bcaa7..d97b3a7097 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_forward.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_forward.c
@@ -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.
*/
@@ -69,7 +69,7 @@
* ERRSRV/<implementation specific>
* ERRHRD/<implementation specific>
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_forward_user_name(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -105,7 +105,7 @@ smb_com_forward_user_name(struct smb_request *sr)
* ERRSRV/<implementation specific>
* ERRHRD/<implementation specific>
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_cancel_forward(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -141,7 +141,7 @@ smb_com_cancel_forward(struct smb_request *sr)
* ERRSRV/ERRinvnid
* ERRSRV/<implementation specific>
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_get_machine_name(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
index 3c2349a482..26774a1516 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
@@ -299,6 +299,7 @@ smb_fsop_create(
smb_attr_t *ret_attr)
{
struct open_param *op = &sr->arg.open;
+ boolean_t no_xvattr = B_FALSE;
smb_node_t *fnode;
smb_attr_t file_attr;
vnode_t *xattrdirvp;
@@ -404,6 +405,31 @@ smb_fsop_create(
return (rc);
}
+ if (sr && sr->tid_tree)
+ if (sr->tid_tree->t_flags & SMB_TREE_FLAG_UFS)
+ no_xvattr = B_TRUE;
+
+ attr->sa_vattr.va_uid = file_attr.sa_vattr.va_uid;
+ attr->sa_vattr.va_gid = file_attr.sa_vattr.va_gid;
+ attr->sa_mask = SMB_AT_UID | SMB_AT_GID;
+
+ /*
+ * The second parameter of smb_vop_setattr() is set to
+ * NULL, even though an unnamed stream exists. This is
+ * because we want to set the UID and GID on the named
+ * stream in this case for consistency with the (unnamed
+ * stream) file (see comments for smb_vop_setattr()).
+ */
+
+ rc = smb_vop_setattr(vp, NULL, attr, 0, kcred, no_xvattr);
+
+ if (rc != 0) {
+ smb_node_release(fnode);
+ kmem_free(fname, MAXNAMELEN);
+ kmem_free(sname, MAXNAMELEN);
+ return (rc);
+ }
+
*ret_snode = smb_stream_node_lookup(sr, cr, fnode, xattrdirvp,
vp, sname, ret_attr);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c b/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c
index d9773cb50f..c626add082 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c
@@ -62,23 +62,22 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_lock_byte_range(struct smb_request *sr)
{
uint32_t count;
uint32_t off;
DWORD result;
+ int rc;
- if (smbsr_decode_vwv(sr, "wll", &sr->smb_fid, &count, &off) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "wll", &sr->smb_fid, &count, &off) != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -91,10 +90,9 @@ smb_com_lock_byte_range(struct smb_request *sr)
(u_offset_t)off, (uint64_t)count, 0, SMB_LOCK_TYPE_READWRITE);
if (result != NT_STATUS_SUCCESS) {
smb_lock_range_error(sr, result);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_empty_result(sr);
-
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c b/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
index b39188ebbd..928f124338 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
@@ -691,7 +691,6 @@ smb_lock_range_error(smb_request_t *sr, uint32_t status32)
errcode = ERRlock;
smbsr_error(sr, status32, ERRDOS, errcode);
- /* NOTREACHED */
}
/*
diff --git a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
index 4aa585091e..9365ff143e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
@@ -213,7 +213,7 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_locking_andx(struct smb_request *sr)
{
unsigned short i;
@@ -232,15 +232,13 @@ smb_com_locking_andx(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, "4.wbblww", &sr->smb_fid, &lock_type,
&oplock_level, &timeout, &unlock_num, &lock_num);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (lock_type & LOCKING_ANDX_SHARED_LOCK)
@@ -275,7 +273,7 @@ smb_com_locking_andx(struct smb_request *sr)
*/
if (lock_type & LOCKING_ANDX_CHANGE_LOCK_TYPE) {
smbsr_error(sr, 0, ERRDOS, ERRnoatomiclocks);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -284,7 +282,7 @@ smb_com_locking_andx(struct smb_request *sr)
if (lock_type & LOCKING_ANDX_CANCEL_LOCK) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
if (lock_type & LOCKING_ANDX_LARGE_FILES) {
@@ -294,7 +292,7 @@ smb_com_locking_andx(struct smb_request *sr)
if (sr->session->dialect < NT_LM_0_12) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
for (i = 0; i < unlock_num; i++) {
@@ -306,7 +304,7 @@ smb_com_locking_andx(struct smb_request *sr)
* even when STATUS32 has been negotiated.
*/
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
@@ -314,7 +312,7 @@ smb_com_locking_andx(struct smb_request *sr)
if (result != NT_STATUS_SUCCESS) {
smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
ERRDOS, ERRnotlocked);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
}
@@ -323,14 +321,14 @@ smb_com_locking_andx(struct smb_request *sr)
&sr->smb_pid, &offset64, &length64);
if (rc) {
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
result = smb_lock_range(sr, sr->fid_ofile,
offset64, length64, timeout, ltype);
if (result != NT_STATUS_SUCCESS) {
smb_lock_range_error(sr, result);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
}
} else {
@@ -339,7 +337,7 @@ smb_com_locking_andx(struct smb_request *sr)
&offset32, &length32);
if (rc) {
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
@@ -347,7 +345,7 @@ smb_com_locking_andx(struct smb_request *sr)
if (result != NT_STATUS_SUCCESS) {
smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
ERRDOS, ERRnotlocked);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
}
@@ -356,7 +354,7 @@ smb_com_locking_andx(struct smb_request *sr)
&offset32, &length32);
if (rc) {
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
result = smb_lock_range(sr, sr->fid_ofile,
@@ -365,13 +363,13 @@ smb_com_locking_andx(struct smb_request *sr)
timeout, ltype);
if (result != NT_STATUS_SUCCESS) {
smb_lock_range_error(sr, result);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
}
}
sr->smb_pid = pid;
- smbsr_encode_result(sr, 2, 0, "bb.ww", 2, sr->andx_com, 7, 0);
-
+ if (smbsr_encode_result(sr, 2, 0, "bb.ww", 2, sr->andx_com, 7, 0))
+ return (SDRC_ERROR_REPLY);
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c b/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
index 4b56c61b73..446e2d4b37 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
@@ -62,16 +62,17 @@
* ERRSRV/invnid - TID was invalid
* ERRSRV/baduid - UID was invalid
*/
-int
+smb_sdrc_t
smb_com_logoff_andx(struct smb_request *sr)
{
if (sr->uid_user == NULL) {
smbsr_error(sr, 0, ERRSRV, ERRbaduid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_user_logoff(sr->uid_user);
- smbsr_encode_result(sr, 2, 0, "bb.ww", 2, sr->andx_com, -1, 0);
+ if (smbsr_encode_result(sr, 2, 0, "bb.ww", 2, sr->andx_com, -1, 0))
+ return (SDRC_ERROR_REPLY);
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c
index d97f410e8b..435e81d842 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c
@@ -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.
*/
@@ -1599,36 +1599,6 @@ smb_decode_vwv(struct smb_request *sr, char *fmt, ...)
int
-smb_decode_data(struct smb_request *sr, char *fmt, ...)
-{
- if (smb_decode_mbc(&sr->smb_data, fmt, (int *)(&fmt + 1)) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
- return (0);
-}
-
-
-void
-smb_encode_header(struct smb_request *sr, int wct,
- int bcc, char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- if (smb_mbc_encode(&sr->reply, fmt, ap) != 0) {
- va_end(ap);
- smbsr_encode_error(sr);
- /* NOTREACHED */
- }
- va_end(ap);
- /*LINTED E_ASSIGN_NARROW_CONV*/
- sr->smb_wct = wct;
- /*LINTED E_ASSIGN_NARROW_CONV*/
- sr->smb_bcc = bcc;
-}
-
-int
smb_peek_mbc(struct mbuf_chain *mbc, int offset, char *fmt, ...)
{
int xx;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_move.c b/usr/src/uts/common/fs/smbsrv/smb_move.c
index eb44e5a84d..d11a5c4049 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_move.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_move.c
@@ -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.
*/
@@ -102,13 +102,10 @@
*/
#include <smbsrv/smb_incl.h>
+
/*ARGSUSED*/
-int
+smb_sdrc_t
smb_com_move(struct smb_request *sr)
{
- /* TODO move */
- /* TODO move wildcards */
- /* TODO move */
-
return (SDRC_UNIMPLEMENTED);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
index a14ae7d3a5..e1d65283aa 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
@@ -240,7 +240,7 @@ static void smb_get_security_info(
* Function: int smb_com_negotiate(struct smb_request *)
*/
-int
+smb_sdrc_t
smb_com_negotiate(struct smb_request *sr)
{
int dialect = 0;
@@ -254,6 +254,7 @@ smb_com_negotiate(struct smb_request *sr)
unsigned short secmode;
uint32_t sesskey;
uint32_t capabilities = 0;
+ int rc;
unsigned short max_mpx_count;
WORD tz_correction;
@@ -262,7 +263,7 @@ smb_com_negotiate(struct smb_request *sr)
if (sr->session->s_state != SMB_SESSION_STATE_ESTABLISHED) {
/* The protocol has already been negotiated. */
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
for (pos = 0;
@@ -270,7 +271,7 @@ smb_com_negotiate(struct smb_request *sr)
pos++) {
if (smb_decode_mbc(&sr->smb_data, "%L", sr, &p) != 0) {
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
this_dialect = smb_xlate_dialect_str_to_cd(p);
@@ -285,7 +286,7 @@ smb_com_negotiate(struct smb_request *sr)
}
if (sel_pos < 0) {
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_get_security_info(sr, &secmode, (unsigned char *)key,
@@ -301,7 +302,7 @@ smb_com_negotiate(struct smb_request *sr)
(void) sosetsockopt(sr->session->sock, SOL_SOCKET, SO_RCVBUF,
(const void *)&smb_dos_tcp_rcvbuf,
sizeof (smb_dos_tcp_rcvbuf));
- smbsr_encode_result(sr, 1, 0, "bww", 1, sel_pos, 0);
+ rc = smbsr_encode_result(sr, 1, 0, "bww", 1, sel_pos, 0);
break;
case Windows_for_Workgroups_3_1a:
@@ -315,7 +316,7 @@ smb_com_negotiate(struct smb_request *sr)
(const void *)&smb_dos_tcp_rcvbuf,
sizeof (smb_dos_tcp_rcvbuf));
sr->smb_flg |= SMB_FLAGS_LOCK_AND_READ_OK;
- smbsr_encode_result(sr, 13, VAR_BCC,
+ rc = smbsr_encode_result(sr, 13, VAR_BCC,
"(wct) b" "(dix) w" "(sec) w" "(mbs) w"
"(mmc) w" "(mnv) w" "(raw) w" "(key) l"
"(tim/dat) Y" "(tz) w" "(ekl) w"
@@ -343,7 +344,7 @@ smb_com_negotiate(struct smb_request *sr)
(const void *)&smb_dos_tcp_rcvbuf,
sizeof (smb_dos_tcp_rcvbuf));
sr->smb_flg |= SMB_FLAGS_LOCK_AND_READ_OK;
- smbsr_encode_result(sr, 13, VAR_BCC,
+ rc = smbsr_encode_result(sr, 13, VAR_BCC,
"(wct) b" "(dix) w" "(sec) w" "(mbs) w"
"(mmc) w" "(mnv) w" "(raw) w" "(key) l"
"(tim/dat) Y" "(tz) w" "(ekl) w"
@@ -411,7 +412,7 @@ smb_com_negotiate(struct smb_request *sr)
/*LINTED E_ASSIGN_NARROW_CONV (uint16_t)*/
max_mpx_count = smb_info.si.skc_maxworkers;
- smbsr_encode_result(sr, 17, VAR_BCC,
+ rc = smbsr_encode_result(sr, 17, VAR_BCC,
"(wct) b" "(dix) w" "(sec) b" "(mmc) w"
"(mnv) w" "(mbs) l" "(raw) l" "(key) l"
"(cap) l" "(tim) T" "(tz) w" "(ekl) b"
@@ -436,9 +437,12 @@ smb_com_negotiate(struct smb_request *sr)
default:
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
+
/*
* Save the agreed dialect. Note that this value is also
* used to detect and reject attempts to re-negotiate.
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c b/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c
index 79334395f0..613974c796 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c
@@ -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.
*/
@@ -45,7 +45,7 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_nt_cancel(struct smb_request *sr)
{
struct smb_request *req;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c
index e7dbe26746..51e3b20937 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c
@@ -167,7 +167,7 @@
* SMB_COM_READ SMB_COM_READ_ANDX
* SMB_COM_IOCTL
*/
-int
+smb_sdrc_t
smb_com_nt_create_andx(struct smb_request *sr)
{
struct open_param *op = &sr->arg.open;
@@ -181,8 +181,6 @@ smb_com_nt_create_andx(struct smb_request *sr)
unsigned short NameLength;
smb_attr_t new_attr;
smb_node_t *node;
- DWORD status;
- int count;
int rc;
op->dsize = 0;
@@ -200,25 +198,21 @@ smb_com_nt_create_andx(struct smb_request *sr)
&ImpersonationLevel,
&SecurityFlags);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
if (NameLength >= MAXPATHLEN) {
smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- if (smbsr_decode_data(sr, "%#u", sr, NameLength, &op->fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%#u", sr, NameLength, &op->fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
!(op->desired_access & DELETE)) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
op->fqi.srch_attr = 0;
@@ -255,42 +249,15 @@ smb_com_nt_create_andx(struct smb_request *sr)
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
op->fqi.dir_snode = sr->fid_ofile->f_node;
smbsr_disconnect_file(sr);
}
- status = NT_STATUS_SUCCESS;
- /*
- * According to NT, when exclusive share access failed,
- * instead of raising "access deny" error immediately,
- * we should wait for the client holding the exclusive
- * file to close the file. If the wait timed out, we
- * report a sharing violation; otherwise, we grant access.
- * smb_open_subr returns NT_STATUS_SHARING_VIOLATION when
- * it encounters an exclusive share access deny: we wait
- * and retry.
- */
- for (count = 0; count <= 4; count++) {
- if (count) {
- delay(MSEC_TO_TICK(400));
- }
-
- if ((status = smb_open_subr(sr)) == NT_STATUS_SUCCESS)
- break;
- }
-
- if (status != NT_STATUS_SUCCESS) {
- if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
- ERRDOS, ERROR_SHARING_VIOLATION);
- else
- smbsr_error(sr, status, 0, 0);
-
- /* NOTREACHED */
- }
+ if (smb_common_open(sr) != NT_STATUS_SUCCESS)
+ return (SDRC_ERROR_REPLY);
if (STYPE_ISDSK(sr->tid_tree->t_res_type)) {
switch (MYF_OPLOCK_TYPE(op->my_flags)) {
@@ -327,7 +294,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
node->attr.sa_vattr.va_size = new_attr.sa_vattr.va_size;
}
- smbsr_encode_result(sr, 34, 0, "bb.wbwlTTTTlqqwwbw",
+ rc = smbsr_encode_result(sr, 34, 0, "bb.wbwlTTTTlqqwwbw",
34,
sr->andx_com,
0x67,
@@ -348,7 +315,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
} else {
/* Named PIPE */
OplockLevel = 0;
- smbsr_encode_result(sr, 34, 0, "bb.wbwlqqqqlqqwwbw",
+ rc = smbsr_encode_result(sr, 34, 0, "bb.wbwlqqqqlqqwwbw",
34,
sr->andx_com,
0x67,
@@ -368,5 +335,5 @@ smb_com_nt_create_andx(struct smb_request *sr)
0);
}
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
index d844733b36..c3439666ac 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
@@ -58,7 +58,7 @@
* security descriptor. For information not defined in CIFS section 4.2.2
* see section 4.2.1 (NT_CREATE_ANDX).
*/
-int
+smb_sdrc_t
smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
{
struct open_param *op = &sr->arg.open;
@@ -94,10 +94,8 @@ smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
&ImpersonationLevel,
&SecurityFlags);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
/*
* If name length is zero, interpret as "\".
@@ -107,23 +105,21 @@ smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
} else {
rc = smb_decode_mbc(&xa->req_param_mb, "%#u",
sr, NameLength, &op->fqi.path);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
}
if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
!(op->desired_access & DELETE)) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sd_len) {
status = smb_decode_sd(xa, &sd);
if (status != NT_STATUS_SUCCESS) {
smbsr_error(sr, status, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
op->sd = &sd;
} else {
@@ -171,19 +167,13 @@ smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
smbsr_disconnect_file(sr);
}
- status = smb_open_subr(sr);
+ status = smb_common_open(sr);
+
if (op->sd)
smb_sd_term(op->sd);
- if (status != NT_STATUS_SUCCESS) {
- if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
- ERRDOS, ERROR_SHARING_VIOLATION);
- else
- smbsr_error(sr, status, 0, 0);
-
- /* NOTREACHED */
- }
+ if (status != NT_STATUS_SUCCESS)
+ return (SDRC_ERROR_REPLY);
if (STYPE_ISDSK(sr->tid_tree->t_res_type)) {
switch (MYF_OPLOCK_TYPE(op->my_flags)) {
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c
index 16fbdbede8..2a1443849d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c
@@ -32,14 +32,14 @@
/*
* This table defines the list of IOCTL/FSCTL values for which we'll
- * return a specific NT status code, based on observation of NT.
+ * return a specific NT status code.
*/
static struct {
uint32_t fcode;
DWORD status;
} ioctl_ret_tbl[] = {
- {FSCTL_GET_OBJECT_ID, NT_STATUS_INVALID_PARAMETER},
- {FSCTL_QUERY_ALLOCATED_RANGES, NT_STATUS_INVALID_PARAMETER}
+ { FSCTL_GET_OBJECT_ID, NT_STATUS_INVALID_PARAMETER },
+ { FSCTL_QUERY_ALLOCATED_RANGES, NT_STATUS_INVALID_PARAMETER }
};
@@ -75,7 +75,7 @@ static struct {
* io or fs control.
* Data[ DataCount ] The results of the io or fs control.
*/
-int
+smb_sdrc_t
smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa)
{
DWORD status = NT_STATUS_SUCCESS;
@@ -86,15 +86,12 @@ smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa)
int i;
if (smb_decode_mbc(&xa->req_setup_mb, "lwbb",
- &fcode,
- &fid,
- &is_fsctl,
- &is_flags) != 0) {
+ &fcode, &fid, &is_fsctl, &is_flags) != 0) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
+ return (SDRC_ERROR_REPLY);
}
- for (i = 0;
- i < sizeof (ioctl_ret_tbl) / sizeof (ioctl_ret_tbl[0]);
+ for (i = 0; i < sizeof (ioctl_ret_tbl) / sizeof (ioctl_ret_tbl[0]);
i++) {
if (ioctl_ret_tbl[i].fcode == fcode) {
status = ioctl_ret_tbl[i].status;
@@ -102,8 +99,10 @@ smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa)
}
}
- if (status != NT_STATUS_SUCCESS)
+ if (status != NT_STATUS_SUCCESS) {
smbsr_error(sr, status, 0, 0);
+ return (SDRC_ERROR_REPLY);
+ }
(void) smb_encode_mbc(&xa->rep_param_mb, "l", 0);
return (SDRC_NORMAL_REPLY);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c
index 264a078a48..0d502e1827 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c
@@ -114,6 +114,8 @@
#include <smbsrv/smb_incl.h>
#include <sys/sdt.h>
+static void smb_reply_notify_change_request(smb_request_t *);
+
/*
* smb_nt_transact_notify_change
*
@@ -122,7 +124,7 @@
* a monitored directory is changed or client cancels one of its already
* sent requests.
*/
-int
+smb_sdrc_t
smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
{
uint32_t CompletionFilter;
@@ -136,7 +138,7 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
node = sr->fid_ofile->f_node;
@@ -146,7 +148,7 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
* Notify change requests are only valid on directories.
*/
smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
mutex_enter(&sr->sr_mutex);
@@ -191,7 +193,8 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
case SMB_REQ_STATE_CANCELED:
mutex_exit(&sr->sr_mutex);
smbsr_error(sr, NT_STATUS_CANCELLED, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
+
default:
ASSERT(0);
mutex_exit(&sr->sr_mutex);
@@ -208,7 +211,7 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
* If client cancels the request or session dropped, an NT_STATUS_CANCELED
* is sent in reply.
*/
-int
+static void
smb_reply_notify_change_request(smb_request_t *sr)
{
smb_node_t *node;
@@ -250,7 +253,7 @@ smb_reply_notify_change_request(smb_request_t *sr)
data_off = param_off + n_param + data_pad;
total_bytes = param_pad + n_param + data_pad + n_data;
- smbsr_encode_result(sr, 18+n_setup, total_bytes,
+ (void) smbsr_encode_result(sr, 18+n_setup, total_bytes,
"b 3. llllllllb C w #. C #. C",
18 + n_setup, /* wct */
n_param, /* Total Parameter Bytes */
@@ -314,7 +317,6 @@ smb_reply_notify_change_request(smb_request_t *sr)
sr->sr_state = SMB_REQ_STATE_COMPLETED;
mutex_exit(&sr->sr_mutex);
smb_request_free(sr);
- return (0);
}
/*
@@ -556,7 +558,7 @@ smb_notify_change_daemon(smb_thread_t *thread, void *si_void)
ASSERT(sr->sr_magic == SMB_REQ_MAGIC);
tmp = list_next(&sr_list, sr);
list_remove(&sr_list, sr);
- (void) smb_reply_notify_change_request(sr);
+ smb_reply_notify_change_request(sr);
sr = tmp;
}
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c
index 69ea40bdb3..cc36dd8282 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c
@@ -67,7 +67,7 @@ static smb_acl_t *smb_decode_acl(struct smb_xa *, uint32_t);
* Data[TotalDataCount] Security Descriptor information
*/
-int
+smb_sdrc_t
smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
{
smb_sd_t sd;
@@ -79,13 +79,13 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
if (smb_decode_mbc(&xa->req_param_mb, "w2.l",
&sr->smb_fid, &secinfo) != 0) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
@@ -93,7 +93,7 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
(sr->fid_ofile->f_ftype != SMB_FTYPE_DISK)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sr->tid_tree->t_acltype != ACE_T) {
@@ -107,14 +107,14 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
status = smb_sd_read(sr, &sd, secinfo);
if (status != NT_STATUS_SUCCESS) {
smbsr_error(sr, status, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sdlen = smb_sd_len(&sd, secinfo);
if (sdlen == 0) {
smb_sd_term(&sd);
smbsr_error(sr, NT_STATUS_INVALID_SECURITY_DESCR, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sdlen > xa->smb_mdrcnt) {
@@ -159,7 +159,7 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
* ================================== ==================================
* Data[TotalDataCount] Security Descriptor information
*/
-int
+smb_sdrc_t
smb_nt_transact_set_security_info(struct smb_request *sr, struct smb_xa *xa)
{
smb_sd_t sd;
@@ -169,24 +169,24 @@ smb_nt_transact_set_security_info(struct smb_request *sr, struct smb_xa *xa)
if (smb_decode_mbc(&xa->req_param_mb, "w2.l",
&sr->smb_fid, &secinfo) != 0) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((sr->fid_ofile->f_node == NULL) ||
(sr->fid_ofile->f_ftype != SMB_FTYPE_DISK)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sr->fid_ofile->f_node->flags & NODE_READ_ONLY) {
smbsr_error(sr, NT_STATUS_MEDIA_WRITE_PROTECTED, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sr->tid_tree->t_acltype != ACE_T) {
@@ -204,20 +204,20 @@ smb_nt_transact_set_security_info(struct smb_request *sr, struct smb_xa *xa)
status = smb_decode_sd(xa, &sd);
if (status != NT_STATUS_SUCCESS) {
smbsr_error(sr, status, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (((secinfo & SMB_OWNER_SECINFO) && (sd.sd_owner == NULL)) ||
((secinfo & SMB_GROUP_SECINFO) && (sd.sd_group == NULL))) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
status = smb_sd_write(sr, &sd, secinfo);
smb_sd_term(&sd);
if (status != NT_STATUS_SUCCESS) {
smbsr_error(sr, status, 0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
return (SDRC_NORMAL_REPLY);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
index 486422d9c5..e693ce43e4 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
@@ -223,23 +223,20 @@
* read nor write the file.
*/
-int
+smb_sdrc_t
smb_com_open(struct smb_request *sr)
{
struct open_param *op = &sr->arg.open;
uint16_t file_attr;
- DWORD status;
+ int rc;
bzero(op, sizeof (sr->arg.open));
- if (smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.srch_attr) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.srch_attr) != 0)
+ return (SDRC_ERROR_REPLY);
+
+ if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
- if (smbsr_decode_data(sr, "%S", sr, &op->fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
op->desired_access = smb_omode_to_amask(op->omode);
op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.path);
@@ -247,7 +244,7 @@ smb_com_open(struct smb_request *sr)
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
op->dsize = 0; /* Don't set spurious size */
@@ -264,27 +261,22 @@ smb_com_open(struct smb_request *sr)
}
}
- if ((status = smb_open_subr(sr)) != NT_STATUS_SUCCESS) {
- if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
- ERRDOS, ERROR_SHARING_VIOLATION);
- else
- smbsr_error(sr, status, 0, 0);
-
- /* NOTREACHED */
- }
+ if (smb_common_open(sr) != NT_STATUS_SUCCESS)
+ return (SDRC_ERROR_REPLY);
if (MYF_OPLOCK_TYPE(op->my_flags) == MYF_OPLOCK_NONE) {
sr->smb_flg &=
~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
}
- if (op->dsize > UINT_MAX)
+ if (op->dsize > UINT_MAX) {
smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
+ return (SDRC_ERROR_REPLY);
+ }
file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
- smbsr_encode_result(sr, 7, 0, "bwwllww",
+ rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
7,
sr->smb_fid,
file_attr,
@@ -293,10 +285,10 @@ smb_com_open(struct smb_request *sr)
op->omode & SMB_DA_ACCESS_MASK,
(uint16_t)0); /* bcc */
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
-int
+smb_sdrc_t
smb_com_open_andx(struct smb_request *sr)
{
struct open_param *op = &sr->arg.open;
@@ -305,8 +297,6 @@ smb_com_open_andx(struct smb_request *sr)
uint16_t granted_access;
uint16_t ofun;
uint16_t file_attr;
- int count;
- DWORD status;
int rc;
bzero(op, sizeof (sr->arg.open));
@@ -314,15 +304,11 @@ smb_com_open_andx(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
&sr->andx_off, &flags, &op->omode, &op->fqi.srch_attr,
&file_attr, &CreationTime, &ofun, &op->dsize, &op->timeo);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
- if (smbsr_decode_data(sr, "%u", sr, &op->fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_data(sr, "%u", sr, &op->fqi.path) != 0)
+ return (SDRC_ERROR_REPLY);
op->desired_access = smb_omode_to_amask(op->omode);
op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.path);
@@ -331,14 +317,14 @@ smb_com_open_andx(struct smb_request *sr)
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
op->dattr = file_attr;
op->create_disposition = smb_ofun_to_crdisposition(ofun);
if (op->create_disposition == ((uint32_t)SMB_INVALID_CRDISPOSITION)) {
smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_PARAMETER);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
op->create_options = (op->omode & SMB_DA_WRITE_THROUGH)
@@ -353,38 +339,13 @@ smb_com_open_andx(struct smb_request *sr)
op->utime.tv_sec = smb_local_time_to_gmt(CreationTime);
op->utime.tv_nsec = 0;
- status = NT_STATUS_SUCCESS;
- /*
- * According to NT, when exclusive share access failed,
- * instead of raising "access deny" error immediately,
- * we should wait for the client holding the exclusive
- * file to close the file. If the wait timed out, we
- * report a sharing violation; otherwise, we grant access.
- * smb_open_subr returns NT_STATUS_SHARING_VIOLATION when
- * it encounters an exclusive share access deny: we wait
- * and retry.
- */
- for (count = 0; count <= 4; count++) {
- if (count) {
- delay(MSEC_TO_TICK(400));
- }
-
- if ((status = smb_open_subr(sr)) == NT_STATUS_SUCCESS)
- break;
- }
-
- if (status != NT_STATUS_SUCCESS) {
- if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
- ERRDOS, ERROR_SHARING_VIOLATION);
- else
- smbsr_error(sr, status, 0, 0);
-
- /* NOTREACHED */
- }
+ if (smb_common_open(sr) != NT_STATUS_SUCCESS)
+ return (SDRC_ERROR_REPLY);
- if (op->dsize > UINT_MAX)
+ if (op->dsize > UINT_MAX) {
smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
+ return (SDRC_ERROR_REPLY);
+ }
if (MYF_OPLOCK_TYPE(op->my_flags) != MYF_OPLOCK_NONE) {
op->action_taken |= SMB_OACT_LOCK;
@@ -398,7 +359,7 @@ smb_com_open_andx(struct smb_request *sr)
file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
if (STYPE_ISDSK(sr->tid_tree->t_res_type)) {
smb_node_t *node = sr->fid_ofile->f_node;
- smbsr_encode_result(sr, 15, 0,
+ rc = smbsr_encode_result(sr, 15, 0,
"b b.w w wll www wl 2. w",
15,
sr->andx_com, VAR_BCC,
@@ -411,7 +372,7 @@ smb_com_open_andx(struct smb_request *sr)
op->action_taken, op->fileid,
0);
} else {
- smbsr_encode_result(sr, 15, 0,
+ rc = smbsr_encode_result(sr, 15, 0,
"b b.w w wll www wl 2. w",
15,
sr->andx_com, VAR_BCC,
@@ -425,5 +386,5 @@ smb_com_open_andx(struct smb_request *sr)
0);
}
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c b/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c
index c31c764bf4..ba446b0f06 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c
@@ -218,6 +218,11 @@ smb_pathname_reduce(
*dir_node = NULL;
*last_component = '\0';
+ if (sr && sr->tid_tree) {
+ if (!STYPE_ISDSK(sr->tid_tree->t_res_type))
+ return (EACCES);
+ }
+
if (SMB_TREE_CASE_INSENSITIVE(sr))
lookup_flags |= FIGNORECASE;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_print.c b/usr/src/uts/common/fs/smbsrv/smb_print.c
index 13f3746b06..ff865fdc2d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_print.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_print.c
@@ -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.
*/
@@ -84,7 +84,7 @@
* ERRSRV/ERRqfull
* ERRSRV/ERRqtoobig
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_open_print_file(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -119,7 +119,7 @@ smb_com_open_print_file(struct smb_request *sr)
* other types of Fid closing requests to invalidate the Fid and begin
* spooling.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_close_print_file(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
@@ -195,17 +195,17 @@ smb_com_close_print_file(struct smb_request *sr)
* ERRHRD/ERRerror
* ERRSRV/ERRbaduid
*/
-int
+smb_sdrc_t
smb_com_get_print_queue(struct smb_request *sr)
{
unsigned short max_count, start_ix;
- if (smbsr_decode_vwv(sr, "ww", &max_count, &start_ix) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "ww", &max_count, &start_ix) != 0)
+ return (SDRC_ERROR_REPLY);
+
+ if (smbsr_encode_result(sr, 2, 3, "bwwwbw", 2, 0, 0, 3, 1, 0))
+ return (SDRC_ERROR_REPLY);
- smbsr_encode_result(sr, 2, 3, "bwwwbw", 2, 0, 0, 3, 1, 0);
return (SDRC_NORMAL_REPLY);
}
@@ -246,7 +246,7 @@ smb_com_get_print_queue(struct smb_request *sr)
* support the application of normal write requests to print spool files.
*
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_write_print_file(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_process_exit.c b/usr/src/uts/common/fs/smbsrv/smb_process_exit.c
index 40d49ea17f..ee43cd499d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_process_exit.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_process_exit.c
@@ -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.
*/
@@ -55,14 +55,16 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_process_exit(struct smb_request *sr)
{
+ int rc;
+
sr->uid_user = smb_user_lookup_by_uid(sr->session, &sr->user_cr,
sr->smb_uid);
if (sr->uid_user == NULL) {
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -79,6 +81,6 @@ smb_com_process_exit(struct smb_request *sr)
smb_tree_close_all_by_pid(sr->uid_user, sr->smb_pid);
}
- smbsr_encode_empty_result(sr);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information.c b/usr/src/uts/common/fs/smbsrv/smb_query_information.c
index 391c3f9c24..0e8fb3019c 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information.c
@@ -65,7 +65,7 @@
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
-int
+smb_sdrc_t
smb_com_query_information(struct smb_request *sr)
{
int rc;
@@ -78,25 +78,31 @@ smb_com_query_information(struct smb_request *sr)
char *name;
timestruc_t *mtime;
- name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- if (smbsr_decode_data(sr, "%S", sr, &path) != 0) {
- kmem_free(name, MAXNAMELEN);
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ 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);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
+ if (smbsr_decode_data(sr, "%S", sr, &path) != 0)
+ return (SDRC_ERROR_REPLY);
+
/*
- * Some MS clients pass NULL file names
- * NT interprets this as "\"
+ * Interpret NULL file names as "\".
*/
- if (strlen(path) == 0) path = "\\";
+ if (strlen(path) == 0)
+ path = "\\";
+
+ name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
if ((rc = smb_pathname_reduce(sr, sr->user_cr, path,
sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dir_node, name))
!= 0) {
kmem_free(name, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
@@ -104,7 +110,7 @@ smb_com_query_information(struct smb_request *sr)
smb_node_release(dir_node);
kmem_free(name, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_node_release(dir_node);
@@ -115,14 +121,14 @@ smb_com_query_information(struct smb_request *sr)
file_size = (uint32_t)smb_node_get_size(node, &node->attr);
smb_node_release(node);
+ kmem_free(name, MAXNAMELEN);
- smbsr_encode_result(sr, 10, 0, "bwll10.w",
+ rc = smbsr_encode_result(sr, 10, 0, "bwll10.w",
10, /* wct */
dattr,
write_time, /* Last write time */
file_size, /* FileSize */
0); /* bcc */
- kmem_free(name, MAXNAMELEN);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information2.c b/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
index d6fa3d1f26..0f5f5018ab 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
@@ -61,29 +61,28 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_query_information2(struct smb_request *sr)
{
smb_node_t *node;
smb_attr_t *attr;
uint32_t dsize, dasize;
unsigned short dattr;
+ int rc;
- if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "w", &sr->smb_fid) != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (sr->fid_ofile->f_ftype != SMB_FTYPE_DISK) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
node = sr->fid_ofile->f_node;
@@ -93,7 +92,7 @@ smb_com_query_information2(struct smb_request *sr)
dasize = attr->sa_vattr.va_blksize * attr->sa_vattr.va_nblocks;
dsize = (dattr & SMB_FA_DIRECTORY) ? 0 : attr->sa_vattr.va_size;
- smbsr_encode_result(sr, 11, 0, "byyyllww",
+ rc = smbsr_encode_result(sr, 11, 0, "byyyllww",
11, /* wct */
smb_gmt_to_local_time(attr->sa_crtime.tv_sec),
/* LastAccessTime */
@@ -105,5 +104,5 @@ smb_com_query_information2(struct smb_request *sr)
dattr, /* FileAttributes */
0); /* bcc */
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c
index 6e38758502..802e74d06f 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c
@@ -67,7 +67,7 @@
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
-int
+smb_sdrc_t
smb_com_query_information_disk(struct smb_request *sr)
{
int rc;
@@ -77,9 +77,16 @@ smb_com_query_information_disk(struct smb_request *sr)
unsigned short blocks_per_unit, bytes_per_block;
unsigned short total_units, free_units;
- if ((rc = smb_fsop_statfs(sr->user_cr, sr->tid_tree->t_snode, &df))
- != 0)
+ if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
+ return (SDRC_ERROR_REPLY);
+ }
+
+ rc = smb_fsop_statfs(sr->user_cr, sr->tid_tree->t_snode, &df);
+ if (rc != 0) {
smbsr_errno(sr, rc);
+ return (SDRC_ERROR_REPLY);
+ }
unit_size = 1;
block_size = df.f_frsize;
@@ -117,7 +124,7 @@ smb_com_query_information_disk(struct smb_request *sr)
bytes_per_block = (unsigned short)block_size;
blocks_per_unit = (unsigned short)unit_size;
- smbsr_encode_result(sr, 5, 0, "bwwww2.w",
+ rc = smbsr_encode_result(sr, 5, 0, "bwwww2.w",
5,
total_units, /* total_units */
blocks_per_unit, /* blocks_per_unit */
@@ -125,5 +132,5 @@ smb_com_query_information_disk(struct smb_request *sr)
free_units, /* free_units */
0); /* bcc */
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_read.c b/usr/src/uts/common/fs/smbsrv/smb_read.c
index fda5c6fdca..7b7aeffa5c 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_read.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_read.c
@@ -37,7 +37,7 @@ typedef struct smb_read_param {
} smb_read_param_t;
-int smb_common_read(struct smb_request *sr, smb_read_param_t *param);
+int smb_common_read(struct smb_request *, smb_read_param_t *);
/*
@@ -55,7 +55,7 @@ int smb_common_read(struct smb_request *sr, smb_read_param_t *param);
* length response is generated. A count returned which is less than the
* count requested is the end of file indicator.
*/
-int
+smb_sdrc_t
smb_com_read(struct smb_request *sr)
{
smb_read_param_t param;
@@ -65,10 +65,8 @@ smb_com_read(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
&param.r_count, &off_low, &remcnt);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
param.r_offset = (uint64_t)off_low;
param.r_mincnt = 0;
@@ -76,18 +74,18 @@ smb_com_read(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((rc = smb_common_read(sr, &param)) != 0) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
+ rc = smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
5, param.r_count, VAR_BCC, 0x01, param.r_count, &sr->raw_data);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -112,7 +110,7 @@ smb_com_read(struct smb_request *sr)
* length response is generated. A count returned which is less than the
* count requested is the end of file indicator.
*/
-int
+smb_sdrc_t
smb_com_lock_and_read(struct smb_request *sr)
{
smb_read_param_t param;
@@ -123,15 +121,13 @@ smb_com_lock_and_read(struct smb_request *sr)
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
&param.r_count, &off_low, &remcnt);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
param.r_offset = (uint64_t)off_low;
param.r_mincnt = 0;
@@ -139,24 +135,25 @@ smb_com_lock_and_read(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
result = smb_lock_range(sr, sr->fid_ofile, param.r_offset,
(uint64_t)param.r_count, UINT_MAX, SMB_LOCK_TYPE_READWRITE);
if (result != NT_STATUS_SUCCESS) {
smb_lock_range_error(sr, result);
+ return (SDRC_ERROR_REPLY);
}
if ((rc = smb_common_read(sr, &param)) != 0) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
+ rc = smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
5, param.r_count, VAR_BCC, 0x1, param.r_count, &sr->raw_data);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -180,7 +177,7 @@ smb_com_lock_and_read(struct smb_request *sr)
*
* Read errors are handled by sending a zero length response.
*/
-int
+smb_sdrc_t
smb_com_read_raw(struct smb_request *sr)
{
smb_read_param_t param;
@@ -204,17 +201,15 @@ smb_com_read_raw(struct smb_request *sr)
param.r_offset = ((uint64_t)off_high << 32) | off_low;
}
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_common_read(sr, &param);
@@ -267,7 +262,7 @@ smb_com_read_raw(struct smb_request *sr)
* LM 0.12 to support 64-bit offsets, indicated by sending a wct of
* 12 and including additional offset information.
*/
-int
+smb_sdrc_t
smb_com_read_andx(struct smb_request *sr)
{
smb_read_param_t param;
@@ -290,22 +285,20 @@ smb_com_read_andx(struct smb_request *sr)
param.r_offset = (uint64_t)off_low;
}
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
param.r_mincnt = 0;
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((rc = smb_common_read(sr, &param)) != 0) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -320,7 +313,7 @@ smb_com_read_andx(struct smb_request *sr)
* is a follow-up to an earlier RPC transaction.
*/
if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
- smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.ww10.wbC",
+ rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.ww10.wbC",
12, /* wct */
secondary, /* Secondary andx command */
offset2, /* offset to next */
@@ -331,7 +324,7 @@ smb_com_read_andx(struct smb_request *sr)
0x02, /* unknown */
&sr->raw_data);
} else {
- smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.ww10.wC",
+ rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.ww10.wC",
12, /* wct */
secondary, /* Secondary andx command */
offset2, /* offset to next */
@@ -342,7 +335,7 @@ smb_com_read_andx(struct smb_request *sr)
&sr->raw_data);
}
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -439,14 +432,14 @@ smb_common_read(struct smb_request *sr, smb_read_param_t *param)
* only over connectionless transports.
*/
/*ARGSUSED*/
-int
+smb_sdrc_t
smb_com_read_mpx(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
}
/*ARGSUSED*/
-int
+smb_sdrc_t
smb_com_read_mpx_secondary(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_rename.c b/usr/src/uts/common/fs/smbsrv/smb_rename.c
index 0239635663..f7a9946972 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_rename.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_rename.c
@@ -53,7 +53,7 @@ static int smb_do_rename(struct smb_request *sr,
* renamed. The encoding of SearchAttributes is described in section 3.10
* - File Attribute Encoding.
*/
-int
+smb_sdrc_t
smb_com_rename(struct smb_request *sr)
{
static kmutex_t mutex;
@@ -65,22 +65,18 @@ smb_com_rename(struct smb_request *sr)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
src_fqi = &sr->arg.dirop.fqi;
dst_fqi = &sr->arg.dirop.dst_fqi;
- if (smbsr_decode_vwv(sr, "w", &src_fqi->srch_attr) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "w", &src_fqi->srch_attr) != 0)
+ return (SDRC_ERROR_REPLY);
rc = smbsr_decode_data(sr, "%SS", sr, &src_fqi->path, &dst_fqi->path);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
dst_fqi->srch_attr = 0;
@@ -101,17 +97,17 @@ smb_com_rename(struct smb_request *sr)
if (rc == EEXIST) {
smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
ERRDOS, ERROR_ALREADY_EXISTS);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (rc == EPIPE) {
smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (src_fqi->dir_snode)
@@ -129,9 +125,8 @@ smb_com_rename(struct smb_request *sr)
SMB_NULL_FQI_NODES(*src_fqi);
SMB_NULL_FQI_NODES(*dst_fqi);
- smbsr_encode_empty_result(sr);
-
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
diff --git a/usr/src/uts/common/fs/smbsrv/smb_rpc.c b/usr/src/uts/common/fs/smbsrv/smb_rpc.c
index 1699af471e..af540e5faf 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_rpc.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_rpc.c
@@ -245,7 +245,7 @@ smb_rpc_initialize(struct smb_request *sr, char *pipe_name)
* residual data remains in the output stream until the client claims
* it or closes the pipe.
*/
-int
+smb_sdrc_t
smb_rpc_transact(struct smb_request *sr, struct uio *uio)
{
struct smb_xa *xa;
@@ -271,7 +271,7 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
smb_rpc_exit(pipe_info);
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERROR_INVALID_HANDLE);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
streamin = &pipe_info->input;
@@ -290,7 +290,7 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
smb_rpc_exit(pipe_info);
smbsr_error(sr, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID,
0, 0);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
diff --git a/usr/src/uts/common/fs/smbsrv/smb_search.c b/usr/src/uts/common/fs/smbsrv/smb_search.c
index d0411e1e58..0a46f8587f 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_search.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_search.c
@@ -130,7 +130,7 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_search(struct smb_request *sr)
{
int rc;
@@ -150,20 +150,16 @@ smb_com_search(struct smb_request *sr)
sr->smb_flg2 &= ~SMB_FLAGS2_KNOWS_LONG_NAMES;
sr->smb_flg &= ~SMB_FLAGS_CASE_INSENSITIVE;
- if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
+ return (SDRC_ERROR_REPLY);
- if ((smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len) != 0) ||
- (type != 0x05)) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ rc = smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len);
+ if ((rc != 0) || (type != 0x05))
+ return (SDRC_ERROR_REPLY);
if ((rc = fsd_getattr(&sr->tid_tree->t_fsd, &vol_attr)) != 0) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
count = 0;
@@ -193,10 +189,12 @@ smb_com_search(struct smb_request *sr)
if (strlen(path) == 0) path = "\\";
rc = smb_rdir_open(sr, path, sattr);
- if (rc == SDRC_NORMAL_REPLY) {
+ if (rc == -1)
+ return (SDRC_ERROR_REPLY);
+ if (rc == -2) {
sr->reply.chain_offset = sr->cur_reply_offset;
(void) smb_encode_mbc(&sr->reply, "bw", 0, 0);
- return (rc);
+ return (SDRC_NORMAL_REPLY);
}
resume_char = 0;
resume_key = 0;
@@ -205,8 +203,7 @@ smb_com_search(struct smb_request *sr)
&resume_char, &cookie, &sr->smb_sid,
&resume_key) != 0) {
/* We don't know which search to close! */
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
@@ -214,12 +211,11 @@ smb_com_search(struct smb_request *sr)
if (sr->sid_odir == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
} else {
/* We don't know which search to close! */
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
(void) smb_encode_mbc(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
@@ -270,13 +266,13 @@ smb_com_search(struct smb_request *sr)
/* returned error by smb_rdir_next() */
smb_rdir_close(sr);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (count == 0) {
smb_rdir_close(sr);
smbsr_error(sr, 0, ERRDOS, ERRnofiles);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_seek.c b/usr/src/uts/common/fs/smbsrv/smb_seek.c
index cffb9ce2d0..fab979cdd6 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_seek.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_seek.c
@@ -79,7 +79,7 @@
* end of file. An attempt to seek before the start of the file sets the
* current file pointer to the start of the file.
*/
-int
+smb_sdrc_t
smb_com_seek(struct smb_request *sr)
{
ushort_t mode;
@@ -87,31 +87,30 @@ smb_com_seek(struct smb_request *sr)
uint32_t off_ret;
int rc;
- if (smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &mode, &off) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &mode, &off) != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- if (mode == SMB_SEEK_END) {
+ if (mode == SMB_SEEK_END)
(void) smb_set_file_size(sr);
- }
if ((rc = smb_ofile_seek(sr->fid_ofile, mode, off, &off_ret)) != 0) {
if (rc == EINVAL) {
smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
} else {
smbsr_error(sr, 0, ERRSRV, ERRerror);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
}
- smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0);
+ if (smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0))
+ return (SDRC_ERROR_REPLY);
+
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_session.c b/usr/src/uts/common/fs/smbsrv/smb_session.c
index 9642aaa76d..00197b76d9 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_session.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_session.c
@@ -1136,16 +1136,7 @@ smb_session_worker(
switch (sr->sr_state) {
case SMB_REQ_STATE_SUBMITTED:
mutex_exit(&sr->sr_mutex);
- if (smb_dispatch_request(sr) < 0) {
- smb_rwx_rwenter(&sr->session->s_lock, RW_WRITER);
- if (sr->session->s_state !=
- SMB_SESSION_STATE_DISCONNECTED) {
- smb_soshutdown(sr->session->sock);
- sr->session->s_state =
- SMB_SESSION_STATE_DISCONNECTED;
- }
- smb_rwx_rwexit(&sr->session->s_lock);
- }
+ smb_dispatch_request(sr);
mutex_enter(&sr->sr_mutex);
if (!sr->sr_keep) {
sr->sr_state = SMB_REQ_STATE_COMPLETED;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c b/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c
index 887a0ca648..e3ec42e912 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c
@@ -227,7 +227,7 @@
#include <smbsrv/smb_token.h>
#include <smbsrv/smb_door_svc.h>
-int
+smb_sdrc_t
smb_com_session_setup_andx(struct smb_request *sr)
{
uint16_t maxbufsize, maxmpxcount, vcnumber = 0;
@@ -256,10 +256,8 @@ smb_com_session_setup_andx(struct smb_request *sr)
&sr->andx_off, &maxbufsize, &maxmpxcount, &vcnumber,
&sesskey, &ci_pwlen, &cs_pwlen, &capabilities);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
ci_password = kmem_alloc(ci_pwlen + 1, KM_SLEEP);
cs_password = kmem_alloc(cs_pwlen + 1, KM_SLEEP);
@@ -288,8 +286,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
if (rc != 0) {
kmem_free(ci_password, ci_pwlen + 1);
kmem_free(cs_password, cs_pwlen + 1);
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
ci_password[ci_pwlen] = 0;
@@ -315,17 +312,14 @@ smb_com_session_setup_andx(struct smb_request *sr)
&sr->andx_off, &maxbufsize, &maxmpxcount,
&vcnumber, &sesskey, &ci_pwlen);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
ci_password = kmem_alloc(ci_pwlen + 1, KM_SLEEP);
rc = smbsr_decode_data(sr, "%#c", sr, ci_pwlen, ci_password);
if (rc != 0) {
kmem_free(ci_password, ci_pwlen + 1);
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
ci_password[ci_pwlen] = 0;
@@ -371,7 +365,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
if (cs_password)
kmem_free(cs_password, cs_pwlen + 1);
smbsr_error(sr, 0, ERRSRV, ERRaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
} else if (utf8_strcasecmp(primary_domain, hostname) == 0) {
/*
* When domain name is equal to hostname, it means
@@ -430,7 +424,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
if (cs_password)
kmem_free(cs_password, cs_pwlen + 1);
smbsr_error(sr, 0, ERRSRV, ERRbadpw);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (usr_token->tkn_session_key) {
@@ -462,7 +456,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
if (session_key)
kmem_free(session_key, sizeof (smb_session_key_t));
smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_HANDLE);
- /* no return */
+ return (SDRC_ERROR_REPLY);
}
sr->user_cr = user->u_cred;
@@ -499,7 +493,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
* and I don't know if a change would cause any problems (see the
* conditional test below).
*/
- smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
+ rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
3,
sr->andx_com,
-1, /* andx_off */
@@ -510,5 +504,5 @@ smb_com_session_setup_andx(struct smb_request *sr)
"NT LAN Manager 4.0",
smb_info.si.skc_resource_domain);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_information.c b/usr/src/uts/common/fs/smbsrv/smb_set_information.c
index e7b1237fa9..c6c4375518 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_set_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_set_information.c
@@ -58,7 +58,7 @@
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
-int
+smb_sdrc_t
smb_com_set_information(struct smb_request *sr)
{
int rc;
@@ -70,34 +70,38 @@ smb_com_set_information(struct smb_request *sr)
struct smb_node *node;
char *name;
+ if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
+ (void) smbsr_encode_empty_result(sr);
+ return (SDRC_NORMAL_REPLY);
+ }
+
name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
if (smbsr_decode_vwv(sr, "wl10.", &dattr, &utime.tv_sec) != 0) {
kmem_free(name, MAXNAMELEN);
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (smbsr_decode_data(sr, "%S", sr, &path) != 0) {
kmem_free(name, MAXNAMELEN);
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
utime.tv_nsec = 0;
- if ((rc = smb_pathname_reduce(sr, sr->user_cr, path,
- sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dir_node, name))
- != 0) {
+ rc = smb_pathname_reduce(sr, sr->user_cr, path,
+ sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dir_node, name);
+ if (rc != 0) {
kmem_free(name, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- if ((rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
- sr->tid_tree->t_snode, dir_node, name, &node, &attr, 0, 0)) != 0) {
+ rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
+ sr->tid_tree->t_snode, dir_node, name, &node, &attr, 0, 0);
+ if (rc != 0) {
smb_node_release(dir_node);
kmem_free(name, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_node_release(dir_node);
@@ -116,13 +120,13 @@ smb_com_set_information(struct smb_request *sr)
rc = smb_sync_fsattr(sr, sr->user_cr, node);
smb_node_release(node);
+ kmem_free(name, MAXNAMELEN);
+
if (rc) {
- kmem_free(name, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_empty_result(sr);
- kmem_free(name, MAXNAMELEN);
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_information2.c b/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
index 8f00ff66d1..aad9a00871 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
@@ -57,7 +57,7 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_set_information2(struct smb_request *sr)
{
unsigned short la_ddate, la_dtime;
@@ -70,22 +70,20 @@ smb_com_set_information2(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, "wwwwwww", &sr->smb_fid, &cr_ddate, &cr_dtime,
&la_ddate, &la_dtime, &lw_ddate, &lw_dtime);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
node = sr->fid_ofile->f_node;
if (node == 0 || sr->fid_ofile->f_ftype != SMB_FTYPE_DISK) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
crtime.tv_nsec = mtime.tv_nsec = atime.tv_nsec = 0;
@@ -112,10 +110,9 @@ smb_com_set_information2(struct smb_request *sr)
rc = smb_sync_fsattr(sr, sr->user_cr, node);
if (rc) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_empty_result(sr);
-
- return (SDRC_NORMAL_REPLY);
+ rc = smbsr_encode_empty_result(sr);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c
index dc85916d04..d87a87efdd 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c
@@ -58,36 +58,38 @@
#include <smbsrv/smb_incl.h>
-extern int smb_common_create_directory(struct smb_request *sr);
-
-
/*
* smb_com_trans2_create_directory
*/
-int
+smb_sdrc_t
smb_com_trans2_create_directory(struct smb_request *sr, struct smb_xa *xa)
{
int rc;
DWORD status;
+ if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERROR_ACCESS_DENIED);
+ return (SDRC_ERROR_REPLY);
+ }
+
if (smb_decode_mbc(&xa->req_param_mb, "%4.s",
sr, &sr->arg.dirop.fqi.path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((status = smb_validate_dirname(sr->arg.dirop.fqi.path)) != 0) {
smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((rc = smb_common_create_directory(sr)) != 0) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (smb_encode_mbc(&xa->rep_param_mb, "w", 0) < 0)
- smbsr_encode_error(sr);
+ return (SDRC_ERROR_REPLY);
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
index 57b3ba257c..b12e4497e1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
@@ -290,7 +290,7 @@ smb_unregister_catia_callback()
* UCHAR Data[ TotalDataCount ] Level dependent info about the matches
* found in the search
*/
-int
+smb_sdrc_t
smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
{
int more = 0, rc;
@@ -307,20 +307,19 @@ smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (smb_decode_mbc(&xa->req_param_mb, "%wwww4.u", sr,
&sattr, &maxcount, &fflag, &infolev, &path) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
if (maxdata == 0) {
smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
ERRDOS, ERROR_INVALID_LEVEL);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -335,7 +334,8 @@ smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
if (sr->smb_flg2 & SMB_FLAGS2_UNICODE)
(void) smb_convert_unicode_wildcards(path);
- (void) smb_rdir_open(sr, path, sattr);
+ if (smb_rdir_open(sr, path, sattr) != 0)
+ return (SDRC_ERROR_REPLY);
/*
* Get a copy of information
@@ -362,7 +362,7 @@ smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
smb_rdir_close(sr);
kmem_free(pattern, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -438,7 +438,7 @@ smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
* UCHAR Data[TotalDataCount] Level dependent info about the
* matches found in the search
*/
-int
+smb_sdrc_t
smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
{
uint16_t fflag, infolev;
@@ -462,14 +462,13 @@ smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
*/
if (smb_decode_mbc(&xa->req_param_mb, "%www lw", sr,
&sr->smb_sid, &maxcount, &infolev, &cookie, &fflag) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree, sr->smb_sid);
if (sr->sid_odir == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
@@ -477,7 +476,7 @@ smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
smb_rdir_close(sr);
smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
ERRDOS, ERROR_INVALID_LEVEL);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -511,7 +510,7 @@ smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
smb_rdir_close(sr);
kmem_free(pattern, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (fflag & SMB_FIND_CLOSE_AFTER_REQUEST ||
@@ -1096,21 +1095,22 @@ smb_trans2_find_mbc_encode(
/*
* Close a search started by a Trans2FindFirst2 request.
*/
-int
+smb_sdrc_t
smb_com_find_close2(smb_request_t *sr)
{
- if (smbsr_decode_vwv(sr, "w", &sr->smb_sid) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "w", &sr->smb_sid) != 0)
+ return (SDRC_ERROR_REPLY);
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree, sr->smb_sid);
if (sr->sid_odir == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_rdir_close(sr);
- smbsr_encode_empty_result(sr);
+
+ if (smbsr_encode_empty_result(sr))
+ return (SDRC_ERROR_REPLY);
+
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
index d4b5443cd9..6e5f6d1296 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
@@ -73,7 +73,7 @@ uint32_t smb_pad_align(uint32_t offset, uint32_t align);
* immediately.
*/
-int
+smb_sdrc_t
smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
{
static smb_attr_t pipe_attr;
@@ -99,14 +99,13 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
if (smb_decode_mbc(&xa->req_param_mb, "ww", &sr->smb_fid,
&infolev) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
switch (sr->fid_ofile->f_ftype) {
@@ -176,8 +175,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
default:
smbsr_error(sr, 0, ERRDOS, ERRbadfile);
- /* NOTREACHED */
- break;
+ return (SDRC_ERROR_REPLY);
}
filebuf = kmem_alloc(MAXNAMELEN+1, KM_SLEEP);
@@ -359,7 +357,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(filebuf, MAXNAMELEN+1);
kmem_free(mangled_name, MAXNAMELEN);
smbsr_error(sr, 0, ERRDOS, ERRbadfile);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
if (SMB_IS_STREAM(node)) {
@@ -386,8 +384,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(filebuf, MAXNAMELEN+1);
kmem_free(mangled_name, MAXNAMELEN);
smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
- /* NOTREACHED */
- break;
+ return (SDRC_ERROR_REPLY);
}
kmem_free(filebuf, MAXNAMELEN+1);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c
index a1820b899e..721ea1e1ad 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c
@@ -261,7 +261,7 @@ is_dot_or_dotdot(char *name)
/*
* smb_com_trans2_query_fs_information
*/
-int
+smb_sdrc_t
smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
{
int rc;
@@ -276,22 +276,25 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
char *fsname = "NTFS";
fsvol_attr_t vol_attr;
- if (smb_decode_mbc(&xa->req_param_mb, "w", &infolev) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
+ return (SDRC_ERROR_REPLY);
}
+ if (smb_decode_mbc(&xa->req_param_mb, "w", &infolev) != 0)
+ return (SDRC_ERROR_REPLY);
+
snode = sr->tid_tree->t_snode;
if (fsd_getattr(&sr->tid_tree->t_fsd, &vol_attr) != 0) {
smbsr_errno(sr, ESTALE);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
switch (infolev) {
case SMB_INFO_ALLOCATION:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
max_int = (uint64_t)UINT_MAX;
@@ -366,7 +369,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
case SMB_QUERY_FS_SIZE_INFO:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
length = 512;
@@ -388,7 +391,6 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO:
-
if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) ||
(sr->session->native_os == NATIVE_OS_WINNT) ||
(sr->session->native_os == NATIVE_OS_WIN2000) ||
@@ -426,8 +428,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
default:
smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
- /* NOTREACHED */
- break;
+ return (SDRC_ERROR_REPLY);
}
return (SDRC_NORMAL_REPLY);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
index bea67e6545..f06fa79d23 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
@@ -324,7 +324,7 @@
/*
* Function: int smb_com_trans2_query_path_information(struct smb_request *)
*/
-int
+smb_sdrc_t
smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
{
char *path, *alt_nm_ptr;
@@ -343,7 +343,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
@@ -355,8 +355,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -383,7 +382,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
@@ -394,7 +393,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smb_node_release(dir_node);
(void) strcpy(name, node->od_name);
@@ -577,9 +576,9 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
- /* NOTREACHED */
- break;
+ return (SDRC_ERROR_REPLY);
}
+
smb_node_release(node);
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
index de71abb6d3..cd315c64cc 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
@@ -101,7 +101,7 @@
/*
* smb_com_trans2_set_file_information
*/
-int
+smb_sdrc_t
smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
{
smb_trans2_setinfo_t *info;
@@ -116,8 +116,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
&info->level);
if (rc != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (!STYPE_ISDSK(sr->tid_tree->t_res_type) ||
@@ -125,14 +124,14 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(info, sizeof (smb_trans2_setinfo_t));
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
info->node = sr->fid_ofile->f_node;
@@ -143,19 +142,19 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(info, sizeof (smb_trans2_setinfo_t));
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
status = smb_trans2_set_information(sr, info, &smberr);
- if (status == NT_STATUS_DATA_ERROR) {
- kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
- } else if (status == NT_STATUS_UNSUCCESSFUL) {
- kmem_free(info, sizeof (smb_trans2_setinfo_t));
+ kmem_free(info, sizeof (smb_trans2_setinfo_t));
+
+ if (status == NT_STATUS_DATA_ERROR)
+ return (SDRC_ERROR_REPLY);
+
+ if (status == NT_STATUS_UNSUCCESSFUL) {
smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- kmem_free(info, sizeof (smb_trans2_setinfo_t));
+
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
index 782e42f36d..d20de1225e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
@@ -97,12 +97,13 @@ smb_trans2_set_information(
return (smb_set_alloc_info(sr, info, smberr));
default:
- smberr->status = NT_STATUS_INVALID_INFO_CLASS;
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_INVALID_PARAMETER;
- return (NT_STATUS_UNSUCCESSFUL);
+ break;
}
- /*NOTREACHED*/
+
+ smberr->status = NT_STATUS_INVALID_INFO_CLASS;
+ smberr->errcls = ERRDOS;
+ smberr->errcode = ERROR_INVALID_PARAMETER;
+ return (NT_STATUS_UNSUCCESSFUL);
}
/*
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
index fd3c2d571f..774793821e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
@@ -110,7 +110,7 @@
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
-int
+smb_sdrc_t
smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
{
smb_trans2_setinfo_t *info;
@@ -127,8 +127,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (smb_decode_mbc(&xa->req_param_mb, "%w4.u", sr, &info->level,
&info->path) != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (!STYPE_ISDSK(sr->tid_tree->t_res_type) ||
@@ -136,7 +135,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(info, sizeof (smb_trans2_setinfo_t));
smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_pathname_reduce(sr, sr->user_cr, info->path,
@@ -146,7 +145,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (rc != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
@@ -158,21 +157,22 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (rc != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
smbsr_errno(sr, rc);
+ return (SDRC_ERROR_REPLY);
}
info->node = ret_snode;
status = smb_trans2_set_information(sr, info, &smberr);
info->node = NULL;
smb_node_release(ret_snode);
- if (status == NT_STATUS_DATA_ERROR) {
- kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
- } else if (status == NT_STATUS_UNSUCCESSFUL) {
- kmem_free(info, sizeof (smb_trans2_setinfo_t));
+ kmem_free(info, sizeof (smb_trans2_setinfo_t));
+
+ if (status == NT_STATUS_DATA_ERROR)
+ return (SDRC_ERROR_REPLY);
+
+ if (status == NT_STATUS_UNSUCCESSFUL) {
smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- kmem_free(info, sizeof (smb_trans2_setinfo_t));
+
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c b/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c
index 9f8d15807e..1899163654 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c
@@ -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.
*/
@@ -67,41 +67,37 @@
#include <smbsrv/smb_incl.h>
-int
+/*
+ * If the negotiated dialect is MICROSOFT NETWORKS 1.03 or earlier,
+ * MaxBufferSize in the response message indicates the maximum size
+ * message that the server can handle. The client should not generate
+ * messages, nor expect to receive responses, larger than this. This
+ * must be constant for a given server. For newer dialects, this field
+ * is ignored.
+ */
+smb_sdrc_t
smb_com_tree_connect(struct smb_request *sr)
{
+ int rc;
+
/*
- * I'm not sure it this should be "%A.sA"
- * now that unicode is enabled.
+ * Perhaps this should be "%A.sA" now that unicode is enabled.
*/
- if (smbsr_decode_data(sr, "%AAA", sr, &sr->arg.tcon.path,
- &sr->arg.tcon.password, &sr->arg.tcon.service) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ rc = smbsr_decode_data(sr, "%AAA", sr, &sr->arg.tcon.path,
+ &sr->arg.tcon.password, &sr->arg.tcon.service);
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
sr->arg.tcon.flags = 0;
- /*
- * If the negotiated dialect is MICROSOFT NETWORKS 1.03
- * or earlier, MaxBufferSize in the response message
- * indicates the maximum size message that the server can
- * handle. The client should not generate messages, nor
- * expect to receive responses, larger than this. This
- * must be constant for a given server. For newer dialects,
- * this field is ignored.
- *
- * The reason for this is that the maximum buffer size is
- * established during the NEGOTIATE.
- */
-
- (void) smbsr_connect_tree(sr);
+ if (smbsr_connect_tree(sr) != 0)
+ return (SDRC_ERROR_REPLY);
- smbsr_encode_result(sr, 2, 0, "bwww",
+ rc = smbsr_encode_result(sr, 2, 0, "bwww",
2, /* wct */
(WORD)smb_maxbufsize, /* MaxBufferSize */
sr->smb_tid, /* TID */
0); /* bcc */
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree_connect_andx.c b/usr/src/uts/common/fs/smbsrv/smb_tree_connect_andx.c
index 436ecf906c..d805dace1d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree_connect_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree_connect_andx.c
@@ -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.
*/
@@ -159,7 +159,7 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_tree_connect_andx(struct smb_request *sr)
{
unsigned char *pwbuf = NULL;
@@ -168,10 +168,8 @@ smb_com_tree_connect_andx(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, "b.www", &sr->andx_com, &sr->andx_off,
&sr->arg.tcon.flags, &pwlen);
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
if (pwlen != 0) {
pwbuf = (unsigned char *)smbsr_malloc(&sr->request_storage,
@@ -179,19 +177,19 @@ smb_com_tree_connect_andx(struct smb_request *sr)
bzero(pwbuf, pwlen);
}
- if (smbsr_decode_data(sr, "%#cus", sr, pwlen, pwbuf,
- &sr->arg.tcon.path, &sr->arg.tcon.service) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ rc = smbsr_decode_data(sr, "%#cus", sr, pwlen, pwbuf,
+ &sr->arg.tcon.path, &sr->arg.tcon.service);
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
sr->arg.tcon.pwdlen = pwlen;
sr->arg.tcon.password = (char *)pwbuf;
- (void) smbsr_connect_tree(sr);
+ if (smbsr_connect_tree(sr) != 0)
+ return (SDRC_ERROR_REPLY);
if (sr->session->dialect < NT_LM_0_12) {
- smbsr_encode_result(sr, 2, VAR_BCC, "bb.wwss",
+ rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.wwss",
(char)2, /* wct */
sr->andx_com,
VAR_BCC,
@@ -199,7 +197,7 @@ smb_com_tree_connect_andx(struct smb_request *sr)
sr->arg.tcon.service,
sr->tid_tree->t_typename);
} else {
- smbsr_encode_result(sr, 3, VAR_BCC, "bb.wwws%u",
+ rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.wwws%u",
(char)3, /* wct */
sr->andx_com,
(short)64,
@@ -209,5 +207,6 @@ smb_com_tree_connect_andx(struct smb_request *sr)
sr,
sr->tid_tree->t_typename);
}
- return (SDRC_NORMAL_REPLY);
+
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c b/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
index 560c1d7b76..83efa87ba4 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
@@ -74,7 +74,7 @@
* For the time being, we will leave it till we have time.
*/
-int
+smb_sdrc_t
smb_com_tree_disconnect(struct smb_request *sr)
{
/*
@@ -101,11 +101,14 @@ smb_com_tree_disconnect(struct smb_request *sr)
if (sr->uid_user == NULL || sr->tid_tree == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRinvnid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
smbsr_rq_notify(sr, sr->session, sr->tid_tree);
smb_tree_disconnect(sr->tid_tree);
- smbsr_encode_empty_result(sr);
+
+ if (smbsr_encode_empty_result(sr))
+ return (SDRC_ERROR_REPLY);
+
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c b/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c
index 8e75fadc36..58a7c93a19 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c
@@ -55,22 +55,20 @@
#include <smbsrv/smb_incl.h>
-int
+smb_sdrc_t
smb_com_unlock_byte_range(struct smb_request *sr)
{
uint32_t Length;
uint32_t Offset;
DWORD result;
- if (smbsr_decode_vwv(sr, "wll", &sr->smb_fid, &Length, &Offset) != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (smbsr_decode_vwv(sr, "wll", &sr->smb_fid, &Length, &Offset) != 0)
+ return (SDRC_ERROR_REPLY);
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
@@ -78,10 +76,11 @@ smb_com_unlock_byte_range(struct smb_request *sr)
if (result != NT_STATUS_SUCCESS) {
smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
ERRDOS, ERRnotlocked);
- /* NOT REACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_empty_result(sr);
+ if (smbsr_encode_empty_result(sr))
+ return (SDRC_ERROR_REPLY);
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c
index a7056d5f3a..db3dd3a1c0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_vops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c
@@ -351,12 +351,21 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
/*
* smb_vop_setattr()
*
- * smb_fsop_setattr()/smb_vop_setattr() should always be called from the CIFS
- * service to set attributes due to special processing for streams files.
+ * smb_fsop_setattr()/smb_vop_setattr() should always be used instead of
+ * VOP_SETATTR() when calling from the CIFS service, due to special processing
+ * for streams files.
*
- * When smb_vop_setattr() is called on a named stream file, all indicated
- * attributes except the size are set on the unnamed stream file. The size
- * (if indicated) is set on the named stream file.
+ * Streams have a size but otherwise do not have separate attributes from
+ * the (unnamed stream) file, i.e., the security and ownership of the file
+ * applies to the stream. In contrast, extended attribute files, which are
+ * used to implement streams, are independent objects with their own
+ * attributes.
+ *
+ * For compatibility with streams, we set the size on the extended attribute
+ * file and apply other attributes to the (unnamed stream) file. The one
+ * exception is that the UID and GID can be set on the stream by passing a
+ * NULL unnamed_vp, which allows callers to synchronize stream ownership
+ * with the (unnamed stream) file.
*/
int
@@ -403,7 +412,8 @@ smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *set_attr,
/*
* If the size of the stream needs to be set, set it on
* the stream file directly. (All other indicated attributes
- * are set on the stream's unnamed stream, above.)
+ * are set on the stream's unnamed stream, except under the
+ * exception described in the function header.)
*/
if (at_size) {
diff --git a/usr/src/uts/common/fs/smbsrv/smb_write.c b/usr/src/uts/common/fs/smbsrv/smb_write.c
index 79a0ed82ec..fdf78eb8e3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_write.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_write.c
@@ -44,9 +44,9 @@ typedef struct smb_write_param {
} smb_write_param_t;
-int smb_write_common(struct smb_request *sr, smb_write_param_t *param);
-int smb_write_truncate(struct smb_request *sr, smb_write_param_t *param);
-int smb_set_file_size(struct smb_request *sr);
+static int smb_write_common(struct smb_request *, smb_write_param_t *);
+static int smb_write_truncate(struct smb_request *, smb_write_param_t *);
+int smb_set_file_size(struct smb_request *);
/*
@@ -59,7 +59,7 @@ int smb_set_file_size(struct smb_request *sr);
* counts differ but there is no error, the client will assume that the
* server encountered a resource issue.
*/
-int
+smb_sdrc_t
smb_com_write(struct smb_request *sr)
{
smb_write_param_t *param;
@@ -71,15 +71,14 @@ smb_com_write(struct smb_request *sr)
rc = smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &param->w_count, &off);
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
param->w_offset = (uint64_t)off;
@@ -92,8 +91,7 @@ smb_com_write(struct smb_request *sr)
if ((rc != 0) || (param->w_vdb.len != param->w_count)) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
param->w_vdb.uio.uio_loffset = (offset_t)param->w_offset;
@@ -104,12 +102,12 @@ smb_com_write(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_result(sr, 1, 0, "bww", 1, param->w_count, 0);
+ rc = smbsr_encode_result(sr, 1, 0, "bww", 1, param->w_count, 0);
kmem_free(param, sizeof (smb_write_param_t));
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -123,7 +121,7 @@ smb_com_write(struct smb_request *sr)
* the mtime. Otherwise the file system stamps the mtime. Failure to
* set mtime should not result in an error response.
*/
-int
+smb_sdrc_t
smb_com_write_and_close(struct smb_request *sr)
{
smb_write_param_t *param;
@@ -143,15 +141,14 @@ smb_com_write_and_close(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
param->w_offset = (uint64_t)off;
@@ -167,8 +164,7 @@ smb_com_write_and_close(struct smb_request *sr)
if ((rc != 0) || (param->w_vdb.len != param->w_count)) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
param->w_vdb.uio.uio_loffset = (offset_t)param->w_offset;
@@ -179,18 +175,18 @@ smb_com_write_and_close(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if ((rc = smb_common_close(sr, last_write)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_result(sr, 1, 0, "bww", 1, param->w_count, 0);
+ rc = smbsr_encode_result(sr, 1, 0, "bww", 1, param->w_count, 0);
kmem_free(param, sizeof (smb_write_param_t));
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -207,7 +203,7 @@ smb_com_write_and_close(struct smb_request *sr)
* counts differ but there is no error, the client will assume that the
* server encountered a resource issue.
*/
-int
+smb_sdrc_t
smb_com_write_and_unlock(struct smb_request *sr)
{
smb_write_param_t *param;
@@ -218,7 +214,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
param = kmem_zalloc(sizeof (smb_write_param_t), KM_SLEEP);
@@ -227,28 +223,26 @@ smb_com_write_and_unlock(struct smb_request *sr)
&remcnt);
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (param->w_count == 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ kmem_free(param, sizeof (smb_write_param_t));
+ return (SDRC_ERROR_REPLY);
}
rc = smbsr_decode_data(sr, "D", &param->w_vdb);
if ((rc != 0) || (param->w_count != param->w_vdb.len)) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
param->w_offset = (uint64_t)off;
@@ -257,7 +251,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
if ((rc = smb_write_common(sr, param)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node, param->w_offset,
@@ -266,12 +260,12 @@ smb_com_write_and_unlock(struct smb_request *sr)
kmem_free(param, sizeof (smb_write_param_t));
smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
ERRDOS, ERRnotlocked);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
- smbsr_encode_result(sr, 1, 0, "bww", 1, param->w_count, 0);
+ rc = smbsr_encode_result(sr, 1, 0, "bww", 1, param->w_count, 0);
kmem_free(param, sizeof (smb_write_param_t));
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -285,7 +279,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
* If bit 0 of WriteMode is set, Fid must refer to a disk file and
* the data must be on stable storage before responding.
*/
-int
+smb_sdrc_t
smb_com_write_andx(struct smb_request *sr)
{
smb_write_param_t *param;
@@ -315,30 +309,28 @@ smb_com_write_andx(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
if (SMB_WRMODE_IS_STABLE(param->w_mode) &&
STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_error(sr, 0, ERRSRV, ERRaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
rc = smbsr_decode_data(sr, "#.#B", data_offset, param->w_count,
&param->w_vdb);
if ((rc != 0) || (param->w_vdb.len != param->w_count)) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
param->w_vdb.uio.uio_loffset = (offset_t)param->w_offset;
@@ -347,15 +339,15 @@ smb_com_write_andx(struct smb_request *sr)
if ((rc = smb_write_common(sr, param)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
smbsr_errno(sr, rc);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
}
- smbsr_encode_result(sr, 6, 0, "bb1.ww6.w",
+ rc = smbsr_encode_result(sr, 6, 0, "bb1.ww6.w",
6, sr->andx_com, 15, param->w_count, 0);
kmem_free(param, sizeof (smb_write_param_t));
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
/*
@@ -363,7 +355,7 @@ smb_com_write_andx(struct smb_request *sr)
*
* Returns errno values.
*/
-int
+static int
smb_write_common(struct smb_request *sr, smb_write_param_t *param)
{
struct smb_ofile *ofile = sr->fid_ofile;
@@ -379,10 +371,8 @@ smb_write_common(struct smb_request *sr, smb_write_param_t *param)
if (node->attr.sa_vattr.va_type != VDIR) {
rc = smb_lock_range_access(sr, node, param->w_offset,
param->w_count, B_TRUE);
- if (rc != NT_STATUS_SUCCESS) {
- smbsr_error(sr, rc, ERRSRV, ERRaccess);
- /* NOTREACHED */
- }
+ if (rc != NT_STATUS_SUCCESS)
+ return (EPERM);
}
if (SMB_WRMODE_IS_STABLE(param->w_mode) ||
@@ -435,46 +425,41 @@ smb_write_common(struct smb_request *sr, smb_write_param_t *param)
*
* Returns errno values.
*/
-int
+static int
smb_write_truncate(struct smb_request *sr, smb_write_param_t *param)
{
struct smb_ofile *ofile = sr->fid_ofile;
smb_node_t *node = ofile->f_node;
boolean_t append_only = B_FALSE;
+ uint32_t status;
int rc;
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0)
return (0);
- rc = smb_ofile_access(sr->fid_ofile, sr->user_cr, FILE_WRITE_DATA);
- if (rc != NT_STATUS_SUCCESS) {
- rc = smb_ofile_access(sr->fid_ofile, sr->user_cr,
+ status = smb_ofile_access(sr->fid_ofile, sr->user_cr, FILE_WRITE_DATA);
+ if (status != NT_STATUS_SUCCESS) {
+ status = smb_ofile_access(sr->fid_ofile, sr->user_cr,
FILE_APPEND_DATA);
- if (rc != NT_STATUS_SUCCESS) {
- smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
- ERROR_ACCESS_DENIED);
- /* NOTREACHED */
- } else {
+ if (status != NT_STATUS_SUCCESS)
+ return (EACCES);
+ else
append_only = B_TRUE;
- }
}
smb_rwx_xenter(&node->n_lock);
if (append_only && (param->w_offset < node->n_size)) {
smb_rwx_xexit(&node->n_lock);
- smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
- ERRDOS, ERRnoaccess);
- /* NOTREACHED */
+ return (EACCES);
}
if (node->attr.sa_vattr.va_type != VDIR) {
- rc = smb_lock_range_access(sr, node, param->w_offset,
+ status = smb_lock_range_access(sr, node, param->w_offset,
param->w_count, B_TRUE);
- if (rc != NT_STATUS_SUCCESS) {
+ if (status != NT_STATUS_SUCCESS) {
smb_rwx_xexit(&node->n_lock);
- smbsr_error(sr, rc, ERRSRV, ERRaccess);
- /* NOTREACHED */
+ return (EACCES);
}
}
@@ -546,12 +531,10 @@ smb_set_file_size(struct smb_request *sr)
* We never send raw write commands to other servers so, if we receive a
* write_complete, we treat it as an error.
*/
-int
+smb_sdrc_t /*ARGSUSED*/
smb_com_write_complete(struct smb_request *sr)
{
- smbsr_decode_error(sr);
- /* NOT REACHED */
- return (0);
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -562,13 +545,13 @@ smb_com_write_complete(struct smb_request *sr)
* connection oriented transports and NT supports SMB_COM_READ_MPX
* only over connectionless transports.
*/
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_write_mpx(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
}
-int /*ARGSUSED*/
+smb_sdrc_t /*ARGSUSED*/
smb_com_write_mpx_secondary(struct smb_request *sr)
{
return (SDRC_UNIMPLEMENTED);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
index 4c7fcb6f81..90d32ab442 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
@@ -199,7 +199,7 @@ static int smb_transfer_write_raw_data(smb_request_t *sr,
#define WR_MODE_WR_THRU 1
-int
+smb_sdrc_t
smb_com_write_raw(struct smb_request *sr)
{
int rc = 0;
@@ -218,9 +218,8 @@ smb_com_write_raw(struct smb_request *sr)
smb_node_t *fnode;
smb_error_t err;
- if (sr->session->s_state != SMB_SESSION_STATE_WRITE_RAW_ACTIVE) {
+ if (sr->session->s_state != SMB_SESSION_STATE_WRITE_RAW_ACTIVE)
return (SDRC_DROP_VC);
- }
if (sr->smb_wct == 12) {
off_high = 0;
@@ -235,10 +234,8 @@ smb_com_write_raw(struct smb_request *sr)
data_offset -= 63;
}
- if (rc != 0) {
- smbsr_decode_error(sr);
- /* NOTREACHED */
- }
+ if (rc != 0)
+ return (SDRC_ERROR_REPLY);
off = ((offset_t)off_high << 32) | off_low;
addl_xfer_count = count - data_length;
@@ -246,7 +243,7 @@ smb_com_write_raw(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
fnode = sr->fid_ofile->f_node;
@@ -263,7 +260,7 @@ smb_com_write_raw(struct smb_request *sr)
count, B_TRUE);
if (rc != NT_STATUS_SUCCESS) {
smbsr_error(sr, rc, ERRSRV, ERRaccess);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
}
}
@@ -275,8 +272,7 @@ smb_com_write_raw(struct smb_request *sr)
if (sr->smb_data.chain_offset + data_offset + data_length >
sr->smb_data.max_bytes) {
/* Error handling code will wake up the session daemon */
- smbsr_decode_error(sr);
- /* NOTREACHED */
+ return (SDRC_ERROR_REPLY);
}
/*
@@ -451,9 +447,9 @@ notify_write_raw_complete:
}
/* Write complete notification */
sr->first_smb_com = SMB_COM_WRITE_COMPLETE;
- smbsr_encode_result(sr, 1, 0, "bww", 1,
+ rc = smbsr_encode_result(sr, 1, 0, "bww", 1,
count - (lcount + addl_lcount), 0);
- return (SDRC_NORMAL_REPLY);
+ return ((rc == 0) ? SDRC_NORMAL_REPLY : SDRC_ERROR_REPLY);
}
diff --git a/usr/src/uts/common/smbsrv/cifs.h b/usr/src/uts/common/smbsrv/cifs.h
index 1f657a2d8c..0734a60727 100644
--- a/usr/src/uts/common/smbsrv/cifs.h
+++ b/usr/src/uts/common/smbsrv/cifs.h
@@ -834,7 +834,7 @@ extern "C" {
#define SV_LOCAL_LIST_ONLY 0x40000000 /* Enumerate only "local" */
#define SV_TYPE_DOMAIN_ENUM 0x80000000 /* Enumerate Domains */
-#define MY_SERVER_TYPE (SV_SERVER | SV_NT | SV_SERVER_NT | SV_DOMAIN_MEMBER)
+#define MY_SERVER_TYPE (SV_SERVER | SV_NT | SV_SERVER_NT)
#define PRQ_ACTIVE 0 /* Active */
diff --git a/usr/src/uts/common/smbsrv/smb_kproto.h b/usr/src/uts/common/smbsrv/smb_kproto.h
index 264e9c5a76..135c2b942e 100644
--- a/usr/src/uts/common/smbsrv/smb_kproto.h
+++ b/usr/src/uts/common/smbsrv/smb_kproto.h
@@ -74,6 +74,108 @@ int smb_service_start_threads(struct smb_info *si);
void smb_service_stop_threads(struct smb_info *si);
/*
+ * SMB request handers called from the dispatcher.
+ */
+smb_sdrc_t smb_com_cancel_forward(struct smb_request *);
+smb_sdrc_t smb_com_check_directory(struct smb_request *);
+smb_sdrc_t smb_com_close(struct smb_request *);
+smb_sdrc_t smb_com_close_and_tree_disconnect(struct smb_request *);
+smb_sdrc_t smb_com_close_print_file(struct smb_request *);
+smb_sdrc_t smb_com_copy(struct smb_request *);
+smb_sdrc_t smb_com_create(struct smb_request *);
+smb_sdrc_t smb_com_create_directory(struct smb_request *);
+smb_sdrc_t smb_com_create_new(struct smb_request *);
+smb_sdrc_t smb_com_create_temporary(struct smb_request *);
+smb_sdrc_t smb_com_delete(struct smb_request *);
+smb_sdrc_t smb_com_delete_directory(struct smb_request *);
+smb_sdrc_t smb_com_echo(struct smb_request *);
+smb_sdrc_t smb_com_find(struct smb_request *);
+smb_sdrc_t smb_com_find_close(struct smb_request *);
+smb_sdrc_t smb_com_find_close2(struct smb_request *);
+smb_sdrc_t smb_com_find_notify_close(struct smb_request *);
+smb_sdrc_t smb_com_find_unique(struct smb_request *);
+smb_sdrc_t smb_com_flush(struct smb_request *);
+smb_sdrc_t smb_com_forward_user_name(struct smb_request *);
+smb_sdrc_t smb_com_get_machine_name(struct smb_request *);
+smb_sdrc_t smb_com_get_print_queue(struct smb_request *);
+smb_sdrc_t smb_com_invalid_command(struct smb_request *);
+smb_sdrc_t smb_com_ioctl(struct smb_request *);
+smb_sdrc_t smb_com_ioctl_secondary(struct smb_request *);
+smb_sdrc_t smb_com_lock_and_read(struct smb_request *);
+smb_sdrc_t smb_com_lock_byte_range(struct smb_request *);
+smb_sdrc_t smb_com_locking_andx(struct smb_request *);
+smb_sdrc_t smb_com_logoff_andx(struct smb_request *);
+smb_sdrc_t smb_com_move(struct smb_request *);
+smb_sdrc_t smb_com_negotiate(struct smb_request *);
+smb_sdrc_t smb_com_nt_cancel(struct smb_request *);
+smb_sdrc_t smb_com_nt_create_andx(struct smb_request *);
+smb_sdrc_t smb_com_nt_transact(struct smb_request *);
+smb_sdrc_t smb_com_nt_transact_secondary(struct smb_request *);
+smb_sdrc_t smb_com_open(struct smb_request *);
+smb_sdrc_t smb_com_open_andx(struct smb_request *);
+smb_sdrc_t smb_com_open_print_file(struct smb_request *);
+smb_sdrc_t smb_com_process_exit(struct smb_request *);
+smb_sdrc_t smb_com_query_information(struct smb_request *);
+smb_sdrc_t smb_com_query_information2(struct smb_request *);
+smb_sdrc_t smb_com_query_information_disk(struct smb_request *);
+smb_sdrc_t smb_com_read(struct smb_request *);
+smb_sdrc_t smb_com_read_andx(struct smb_request *);
+smb_sdrc_t smb_com_read_mpx(struct smb_request *);
+smb_sdrc_t smb_com_read_mpx_secondary(struct smb_request *);
+smb_sdrc_t smb_com_read_raw(struct smb_request *);
+smb_sdrc_t smb_com_rename(struct smb_request *);
+smb_sdrc_t smb_com_search(struct smb_request *);
+smb_sdrc_t smb_com_seek(struct smb_request *);
+smb_sdrc_t smb_com_send_broadcast_message(struct smb_request *);
+smb_sdrc_t smb_com_send_end_mb_message(struct smb_request *);
+smb_sdrc_t smb_com_send_single_message(struct smb_request *);
+smb_sdrc_t smb_com_send_start_mb_message(struct smb_request *);
+smb_sdrc_t smb_com_send_text_mb_message(struct smb_request *);
+smb_sdrc_t smb_com_session_setup_andx(struct smb_request *);
+smb_sdrc_t smb_com_set_information(struct smb_request *);
+smb_sdrc_t smb_com_set_information2(struct smb_request *);
+smb_sdrc_t smb_com_transaction(struct smb_request *);
+smb_sdrc_t smb_com_transaction2(struct smb_request *);
+smb_sdrc_t smb_com_transaction2_secondary(struct smb_request *);
+smb_sdrc_t smb_com_transaction_secondary(struct smb_request *);
+smb_sdrc_t smb_com_tree_connect(struct smb_request *);
+smb_sdrc_t smb_com_tree_connect_andx(struct smb_request *);
+smb_sdrc_t smb_com_tree_disconnect(struct smb_request *);
+smb_sdrc_t smb_com_unlock_byte_range(struct smb_request *);
+smb_sdrc_t smb_com_write(struct smb_request *);
+smb_sdrc_t smb_com_write_and_close(struct smb_request *);
+smb_sdrc_t smb_com_write_and_unlock(struct smb_request *);
+smb_sdrc_t smb_com_write_andx(struct smb_request *);
+smb_sdrc_t smb_com_write_complete(struct smb_request *);
+smb_sdrc_t smb_com_write_mpx(struct smb_request *);
+smb_sdrc_t smb_com_write_mpx_secondary(struct smb_request *);
+smb_sdrc_t smb_com_write_print_file(struct smb_request *);
+smb_sdrc_t smb_com_write_raw(struct smb_request *);
+
+smb_sdrc_t smb_nt_transact_create(struct smb_request *, struct smb_xa *);
+smb_sdrc_t smb_nt_transact_notify_change(struct smb_request *, struct smb_xa *);
+smb_sdrc_t smb_nt_transact_query_security_info(struct smb_request *,
+ struct smb_xa *);
+smb_sdrc_t smb_nt_transact_set_security_info(struct smb_request *,
+ struct smb_xa *);
+smb_sdrc_t smb_nt_transact_ioctl(struct smb_request *, struct smb_xa *);
+
+smb_sdrc_t smb_com_trans2_create_directory(struct smb_request *,
+ struct smb_xa *);
+smb_sdrc_t smb_com_trans2_find_first2(struct smb_request *, struct smb_xa *);
+smb_sdrc_t smb_com_trans2_find_next2(struct smb_request *, struct smb_xa *);
+smb_sdrc_t smb_com_trans2_query_fs_information(struct smb_request *,
+ struct smb_xa *);
+smb_sdrc_t smb_com_trans2_query_path_information(struct smb_request *,
+ struct smb_xa *);
+smb_sdrc_t smb_com_trans2_query_file_information(struct smb_request *,
+ struct smb_xa *);
+smb_sdrc_t smb_com_trans2_set_path_information(struct smb_request *,
+ struct smb_xa *);
+smb_sdrc_t smb_com_trans2_set_file_information(struct smb_request *,
+ struct smb_xa *);
+
+/*
* Logging functions
*/
void smb_log_flush(void);
@@ -125,6 +227,8 @@ void smbsr_cleanup(struct smb_request *sr);
int smbsr_connect_tree(struct smb_request *);
+int smb_common_create_directory(struct smb_request *);
+
int smb_convert_unicode_wildcards(char *);
int smb_ascii_or_unicode_strlen(struct smb_request *, char *);
int smb_ascii_or_unicode_strlen_null(struct smb_request *, char *);
@@ -136,24 +240,21 @@ int smb_rdir_open(struct smb_request *, char *, unsigned short);
int smb_rdir_next(smb_request_t *sr, smb_node_t **rnode,
smb_odir_context_t *pc);
-DWORD smb_open_subr(struct smb_request *);
+uint32_t smb_common_open(smb_request_t *);
DWORD smb_validate_object_name(char *path, unsigned int ftype);
uint32_t smb_omode_to_amask(uint32_t desired_access);
void sshow_distribution_info(char *);
-int smb_dispatch_request(struct smb_request *);
-void smbsr_disconnect_file(smb_request_t *sr);
-void smbsr_disconnect_dir(smb_request_t *sr);
-void smbsr_check_result(struct smb_request *, int, int);
-void smbsr_decode_error(struct smb_request *);
-void smbsr_encode_error(struct smb_request *);
-void smbsr_encode_empty_result(struct smb_request *sr);
+void smb_dispatch_request(struct smb_request *);
+void smbsr_disconnect_file(smb_request_t *);
+void smbsr_disconnect_dir(smb_request_t *);
+int smbsr_encode_empty_result(struct smb_request *);
int smbsr_decode_vwv(struct smb_request *sr, char *fmt, ...);
int smbsr_decode_data(struct smb_request *sr, char *fmt, ...);
-void smbsr_encode_result(struct smb_request *, int, int, char *, ...);
+int smbsr_encode_result(struct smb_request *, int, int, char *, ...);
smb_xa_t *smbsr_lookup_xa(smb_request_t *sr);
void smbsr_send_reply(struct smb_request *);
@@ -212,11 +313,11 @@ int smb_net_txb_send(struct sonode *, smb_txlst_t *, smb_txbuf_t *);
/*
* SMB RPC interface
*/
-int smb_rpc_open(struct smb_request *sr);
-void smb_rpc_close(struct smb_ofile *of);
-int smb_rpc_transact(struct smb_request *sr, struct uio *uio);
-int smb_rpc_read(struct smb_request *sr, struct uio *uio);
-int smb_rpc_write(struct smb_request *sr, struct uio *uio);
+int smb_rpc_open(struct smb_request *);
+void smb_rpc_close(struct smb_ofile *);
+smb_sdrc_t smb_rpc_transact(struct smb_request *, struct uio *);
+int smb_rpc_read(struct smb_request *, struct uio *);
+int smb_rpc_write(struct smb_request *, struct uio *);
/*
* SMB node functions (file smb_node.c)
@@ -296,36 +397,13 @@ char *smb_kstrdup(const char *s, size_t n);
int smb_sync_fsattr(struct smb_request *sr, cred_t *cr,
struct smb_node *node);
-int smb_com_create_directory(struct smb_request *sr);
DWORD smb_validate_dirname(char *path);
-int smb_com_trans2_create_directory(struct smb_request *sr, struct smb_xa *xa);
-int smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa);
-int smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa);
-int smb_com_trans2_query_fs_information(struct smb_request *sr,
- struct smb_xa *xa);
-int smb_com_trans2_query_path_information(
- struct smb_request *sr, struct smb_xa *xa);
-int smb_com_trans2_query_file_information(
- struct smb_request *sr, struct smb_xa *xa);
-int smb_com_trans2_set_path_information(
- struct smb_request *sr, struct smb_xa *xa);
-int smb_com_trans2_set_file_information(
- struct smb_request *sr, struct smb_xa *xa);
void smb_encode_stream_info(struct smb_request *sr, struct smb_xa *xa,
smb_node_t *snode, smb_attr_t *attr);
-int smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa);
-int smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa);
-int smb_nt_transact_query_security_info(struct smb_request *sr,
- struct smb_xa *xa);
-int smb_nt_transact_set_security_info(struct smb_request *sr,
- struct smb_xa *xa);
-int smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa);
-
/* NOTIFY CHANGE */
-int smb_reply_notify_change_request(smb_request_t *sr);
void smb_process_session_notify_change_queue(struct smb_session *session);
void smb_process_node_notify_change_queue(struct smb_node *node);
void smb_reply_specific_cancel_request(struct smb_request *sr);
diff --git a/usr/src/uts/common/smbsrv/smb_winpipe.h b/usr/src/uts/common/smbsrv/smb_winpipe.h
index 22b258ad02..4e4f383543 100755
--- a/usr/src/uts/common/smbsrv/smb_winpipe.h
+++ b/usr/src/uts/common/smbsrv/smb_winpipe.h
@@ -46,7 +46,7 @@ extern "C" {
#define SMB_IO_MAX_SIZE 32
#define SMB_MAX_PIPENAMELEN 32
-
+#define SMB_CTXT_PIPE_SZ 65536
#define SMB_WINPIPE_DOOR_DOWN_PATH "/var/run/winpipe_doordown"
#define SMB_DOWNCALLINFO_MAGIC 0x19121969
diff --git a/usr/src/uts/common/smbsrv/smbvar.h b/usr/src/uts/common/smbsrv/smbvar.h
index 316c10e814..7963922a3e 100644
--- a/usr/src/uts/common/smbsrv/smbvar.h
+++ b/usr/src/uts/common/smbsrv/smbvar.h
@@ -981,6 +981,12 @@ struct smb_fqi { /* fs_query_info */
#define OPLOCK_MIN_TIMEOUT (5 * 1000)
#define OPLOCK_STD_TIMEOUT (15 * 1000)
+typedef struct {
+ uint32_t severity;
+ uint32_t status;
+ uint16_t errcls;
+ uint16_t errcode;
+} smb_error_t;
/*
* SMB Request State Machine
@@ -1148,9 +1154,12 @@ struct smb_request {
unsigned int reply_seqnum; /* reply sequence number */
unsigned char first_smb_com; /* command code */
unsigned char smb_com; /* command code */
- unsigned char smb_rcls; /* error code class */
- unsigned char smb_reh; /* rsvd (AH DOS INT-24 ERR) */
+
+ uint8_t smb_rcls; /* error code class */
+ uint8_t smb_reh; /* rsvd (AH DOS INT-24 ERR) */
uint16_t smb_err; /* error code */
+ smb_error_t smb_error;
+
uint8_t smb_flg; /* flags */
uint16_t smb_flg2; /* flags */
uint16_t smb_pid_high; /* high part of pid */
@@ -1216,7 +1225,6 @@ struct smb_request {
} arg;
- label_t exjb;
cred_t *user_cr;
};
@@ -1301,13 +1309,17 @@ typedef struct smb_xa {
#define SDDF_SUPPRESS_UNLEASH 0x0004
#define SDDF_SUPPRESS_SHOW 0x0080
-#define SDRC_NORMAL_REPLY 0
-#define SDRC_DROP_VC 1
-#define SDRC_NO_REPLY 2
-#define SDRC_ERROR_REPLY 3
-#define SDRC_UNIMPLEMENTED 4
-#define SDRC_UNSUPPORTED 5
-
+/*
+ * SMB dispatch return codes.
+ */
+typedef enum {
+ SDRC_NORMAL_REPLY = 0,
+ SDRC_DROP_VC,
+ SDRC_NO_REPLY,
+ SDRC_ERROR_REPLY,
+ SDRC_UNIMPLEMENTED,
+ SDRC_UNSUPPORTED
+} smb_sdrc_t;
struct vardata_block {
unsigned char tag;
@@ -1374,13 +1386,6 @@ typedef struct smb_info {
#define SMB_NEW_KID() atomic_inc_64_nv(&smb_info.si_global_kid)
#define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_info.si_uniq_fid)
-typedef struct {
- uint32_t severity;
- uint32_t status;
- uint16_t errcls;
- uint16_t errcode;
-} smb_error_t;
-
/*
* This is to be used by Trans2SetFileInfo
* and Trans2SetPathInfo
@@ -1411,7 +1416,7 @@ typedef struct smb_tsd {
#define SMB_INVALID_CRDISPOSITION -1
typedef struct smb_dispatch_table {
- int (*sdt_function)(struct smb_request *);
+ smb_sdrc_t (*sdt_function)(struct smb_request *);
char sdt_dialect;
unsigned char sdt_flags;
krw_t sdt_slock_mode;