summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fs.d/nfs/mountd/Makefile4
-rw-r--r--usr/src/cmd/fs.d/nfs/mountd/mountd.c86
-rw-r--r--usr/src/cmd/fs.d/nfs/svc/server.xml2
-rw-r--r--usr/src/lib/libshare/nfs/libshare_nfs.c9
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c30
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c27
-rw-r--r--usr/src/man/man5/nfs.512
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_fsctl_odx.c52
8 files changed, 190 insertions, 32 deletions
diff --git a/usr/src/cmd/fs.d/nfs/mountd/Makefile b/usr/src/cmd/fs.d/nfs/mountd/Makefile
index 505ab301e3..43b1ec62ac 100644
--- a/usr/src/cmd/fs.d/nfs/mountd/Makefile
+++ b/usr/src/cmd/fs.d/nfs/mountd/Makefile
@@ -24,6 +24,7 @@
# Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
#
# Copyright (c) 2018, Joyent, Inc.
+# Copyright 2022 RackTop Systems.
FSTYPE = nfs
TYPEPROG = mountd
@@ -39,7 +40,8 @@ SRCS = $(LOCAL:%.o=%.c) $(FSLIBSRC) ../lib/nfs_sec.c \
../lib/sharetab.c ../lib/daemon.c ../lib/smfcfg.c
DSRC = mountd_dt.d
DOBJ = $(DSRC:%.d=%.o)
-LDLIBS += -lrpcsvc -lnsl -lbsm -lsocket -ltsnet -ltsol -lnvpair -lscf -lumem
+LDLIBS += -lrpcsvc -lnsl -lbsm -lsocket -linetutil -ltsnet -ltsol
+LDLIBS += -lnvpair -lscf -lumem
CPPFLAGS += -D_REENTRANT -I../lib
CERRWARN += $(CNOWARN_UNINIT)
diff --git a/usr/src/cmd/fs.d/nfs/mountd/mountd.c b/usr/src/cmd/fs.d/nfs/mountd/mountd.c
index 1816deabc6..9df7f2f9a9 100644
--- a/usr/src/cmd/fs.d/nfs/mountd/mountd.c
+++ b/usr/src/cmd/fs.d/nfs/mountd/mountd.c
@@ -23,6 +23,7 @@
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2022 RackTop Systems.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -88,6 +89,8 @@
#include <pwd.h>
#include <grp.h>
#include <alloca.h>
+#include <libinetutil.h>
+#include <libsocket_priv.h>
extern int daemonize_init(void);
extern void daemonize_fini(int);
@@ -124,6 +127,7 @@ static int rejecting;
static int mount_vers_min = MOUNTVERS;
static int mount_vers_max = MOUNTVERS3;
static int mountd_port = 0;
+static boolean_t mountd_remote_dump = B_FALSE;
extern void nfscmd_func(void *, char *, size_t, door_desc_t *, uint_t);
@@ -150,6 +154,9 @@ static logging_data *logging_tail = NULL;
static long ngroups_max; /* _SC_NGROUPS_MAX */
static long pw_size; /* _SC_GETPW_R_SIZE_MAX */
+/* Cached address info for this host. */
+static struct addrinfo *host_ai = NULL;
+
static void *
nfsauth_svc(void *arg __unused)
{
@@ -435,7 +442,7 @@ main(int argc, char *argv[])
bool_t exclbind = TRUE;
bool_t can_do_mlp;
long thr_flags = (THR_NEW_LWP|THR_DAEMON);
- char defval[4];
+ char defval[5];
int defvers, ret, bufsz;
struct rlimit rl;
int listen_backlog = 0;
@@ -445,6 +452,7 @@ main(int argc, char *argv[])
NCONF_HANDLE *nc;
const char *errstr;
int pipe_fd = -1;
+ char hostbuf[256];
/*
* Mountd requires uid 0 for:
@@ -533,7 +541,7 @@ main(int argc, char *argv[])
/*
* Read in the NFS version values from config file.
*/
- bufsz = 4;
+ bufsz = sizeof (defval);
ret = nfs_smf_get_prop("server_versmin", defval, DEFAULT_INSTANCE,
SCF_TYPE_INTEGER, NFSD, &bufsz);
if (ret == SA_OK) {
@@ -550,7 +558,7 @@ main(int argc, char *argv[])
}
}
- bufsz = 4;
+ bufsz = sizeof (defval);
ret = nfs_smf_get_prop("server_versmax", defval, DEFAULT_INSTANCE,
SCF_TYPE_INTEGER, NFSD, &bufsz);
if (ret == SA_OK) {
@@ -568,6 +576,24 @@ main(int argc, char *argv[])
"failed, using default value");
}
+ bufsz = sizeof (defval);
+ ret = nfs_smf_get_prop("mountd_remote_dump", defval, DEFAULT_INSTANCE,
+ SCF_TYPE_BOOLEAN, NFSD, &bufsz);
+ if (ret == SA_OK) {
+ mountd_remote_dump = string_to_boolean(defval);
+ }
+ if (!mountd_remote_dump) {
+ /* Cache host address list */
+ if (gethostname(hostbuf, sizeof (hostbuf)) < 0) {
+ syslog(LOG_ERR, "gethostname() failed");
+ exit(1);
+ }
+ if (getaddrinfo(hostbuf, NULL, NULL, &host_ai) != 0) {
+ syslog(LOG_ERR, "getaddrinfo() failed");
+ exit(1);
+ }
+ }
+
/*
* Sanity check versions,
* even though we may get versions > MOUNTVERS3, we still need
@@ -781,6 +807,55 @@ main(int argc, char *argv[])
}
/*
+ * copied from usr/src/uts/common/klm/nlm_impl.c
+ */
+static bool_t
+caller_is_local(SVCXPRT *transp)
+{
+ struct addrinfo *a;
+ char *netid;
+ struct netbuf *rtaddr;
+ struct sockaddr_storage addr;
+ bool_t rv = FALSE;
+
+ netid = transp->xp_netid;
+ rtaddr = svc_getrpccaller(transp);
+
+ if (netid == NULL)
+ return (FALSE);
+
+ if (strcmp(netid, "ticlts") == 0 ||
+ strcmp(netid, "ticotsord") == 0)
+ return (TRUE);
+
+ if (strcmp(netid, "tcp") == 0 || strcmp(netid, "udp") == 0) {
+ struct sockaddr_in *sin = (void *)rtaddr->buf;
+
+ if (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK))
+ return (TRUE);
+
+ memmove(&addr, sin, sizeof (*sin));
+ }
+ if (strcmp(netid, "tcp6") == 0 || strcmp(netid, "udp6") == 0) {
+ struct sockaddr_in6 *sin6 = (void *)rtaddr->buf;
+
+ if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
+ return (TRUE);
+
+ memmove(&addr, sin6, sizeof (*sin6));
+ }
+
+ for (a = host_ai; a != NULL; a = a->ai_next) {
+ if (sockaddrcmp(&addr,
+ (struct sockaddr_storage *)a->ai_addr)) {
+ rv = TRUE;
+ break;
+ }
+ }
+ return (rv);
+}
+
+/*
* Server procedure switch routine
*/
void
@@ -798,7 +873,10 @@ mnt(struct svc_req *rqstp, SVCXPRT *transp)
return;
case MOUNTPROC_DUMP:
- mntlist_send(transp);
+ if (mountd_remote_dump || caller_is_local(transp))
+ mntlist_send(transp);
+ else
+ svcerr_noproc(transp);
return;
case MOUNTPROC_UMNT:
diff --git a/usr/src/cmd/fs.d/nfs/svc/server.xml b/usr/src/cmd/fs.d/nfs/svc/server.xml
index 9393d9da55..1e78742670 100644
--- a/usr/src/cmd/fs.d/nfs/svc/server.xml
+++ b/usr/src/cmd/fs.d/nfs/svc/server.xml
@@ -26,6 +26,7 @@
Copyright 2014 Nexenta Systems, Inc. All rights reserved
Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ Copyright 2022 RackTop Systems.
NOTE: This service manifest is not editable; its contents will
be overwritten by package or patch operations, including
@@ -180,6 +181,7 @@
<propval name='mountd_listen_backlog' type='integer' value='64'/>
<propval name='mountd_max_threads' type='integer' value='16'/>
<propval name='mountd_port' type='integer' value='0'/>
+ <propval name='mountd_remote_dump' type='boolean' value='false'/>
</property_group>
</instance>
diff --git a/usr/src/lib/libshare/nfs/libshare_nfs.c b/usr/src/lib/libshare/nfs/libshare_nfs.c
index 57118ce038..7c630e37a2 100644
--- a/usr/src/lib/libshare/nfs/libshare_nfs.c
+++ b/usr/src/lib/libshare/nfs/libshare_nfs.c
@@ -24,6 +24,7 @@
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
* Copyright 2018 Nexenta Systems, Inc.
+ * Copyright 2022 RackTop Systems.
*/
/*
@@ -2521,8 +2522,12 @@ struct proto_option_defs {
#define PROTO_OPT_MOUNTD_PORT 17
{"mountd_port",
"mountd_port", PROTO_OPT_MOUNTD_PORT,
- OPT_TYPE_NUMBER, 0, SVC_MOUNTD, 1, UINT16_MAX},
-#define PROTO_OPT_STATD_PORT 18
+ OPT_TYPE_NUMBER, 0, SVC_NFSD|SVC_MOUNTD, 1, UINT16_MAX},
+#define PROTO_OPT_MOUNTD_REMOTE_DUMP 18
+ {"mountd_remote_dump",
+ "mountd_remote_dump", PROTO_OPT_MOUNTD_REMOTE_DUMP,
+ OPT_TYPE_BOOLEAN, B_FALSE, SVC_NFSD|SVC_MOUNTD, B_FALSE, B_TRUE},
+#define PROTO_OPT_STATD_PORT 19
{"statd_port",
"statd_port", PROTO_OPT_STATD_PORT,
OPT_TYPE_NUMBER, 0, SVC_STATD, 1, UINT16_MAX},
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
index f56838303f..ebf454da5c 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2020 Tintri by DDN, Inc. All rights reserved.
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
/*
@@ -457,8 +457,11 @@ netr_gen_skey128(netr_info_t *netr_info)
}
rc = smb_auth_ntlm_hash((char *)netr_info->password, ntlmhash);
- if (rc != SMBAUTH_SUCCESS)
+ if (rc != SMBAUTH_SUCCESS) {
+ explicit_bzero(&netr_info->password,
+ sizeof (netr_info->password));
return (SMBAUTH_FAILURE);
+ }
bzero(zerobuf, NETR_SESSKEY_ZEROBUF_SZ);
@@ -467,8 +470,10 @@ netr_gen_skey128(netr_info_t *netr_info)
mechanism.ulParameterLen = 0;
rv = SUNW_C_GetMechSession(mechanism.mechanism, &hSession);
- if (rv != CKR_OK)
- return (SMBAUTH_FAILURE);
+ if (rv != CKR_OK) {
+ rc = SMBAUTH_FAILURE;
+ goto errout;
+ }
rv = C_DigestInit(hSession, &mechanism);
if (rv != CKR_OK)
@@ -499,6 +504,11 @@ netr_gen_skey128(netr_info_t *netr_info)
netr_info->session_key.len = NETR_SESSKEY128_SZ;
cleanup:
(void) C_CloseSession(hSession);
+
+errout:
+ explicit_bzero(&netr_info->password, sizeof (netr_info->password));
+ explicit_bzero(ntlmhash, sizeof (ntlmhash));
+
return (rc);
}
@@ -563,8 +573,10 @@ netr_gen_skey64(netr_info_t *netr_info)
rc = smb_auth_ntlm_hash((char *)netr_info->password, md4hash);
- if (rc != SMBAUTH_SUCCESS)
- return (SMBAUTH_FAILURE);
+ if (rc != SMBAUTH_SUCCESS) {
+ rc = SMBAUTH_FAILURE;
+ goto out;
+ }
data[0] = LE_IN32(&client_challenge[0]) + LE_IN32(&server_challenge[0]);
data[1] = LE_IN32(&client_challenge[1]) + LE_IN32(&server_challenge[1]);
@@ -574,13 +586,17 @@ netr_gen_skey64(netr_info_t *netr_info)
(unsigned char *)le_data, 8);
if (rc != SMBAUTH_SUCCESS)
- return (rc);
+ goto out;
netr_info->session_key.len = NETR_SESSKEY64_SZ;
rc = smb_auth_DES(netr_info->session_key.key,
netr_info->session_key.len, &md4hash[9], NETR_DESKEY_LEN, buffer,
8);
+out:
+ explicit_bzero(&netr_info->password, sizeof (netr_info->password));
+ explicit_bzero(md4hash, sizeof (md4hash));
+ explicit_bzero(buffer, sizeof (buffer));
return (rc);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
index e82722b257..024fda129e 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2020 Tintri by DDN, Inc. All rights reserved.
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
/*
@@ -49,7 +49,7 @@
uint32_t netlogon_logon(smb_logon_t *, smb_token_t *, smb_domainex_t *);
static uint32_t netr_server_samlogon(mlsvc_handle_t *, netr_info_t *, char *,
smb_logon_t *, smb_token_t *);
-static void netr_invalidate_chain(void);
+static void netr_invalidate_chain(netr_info_t *);
static void netr_interactive_samlogon(netr_info_t *, smb_logon_t *,
struct netr_logon_info1 *);
static void netr_network_samlogon(ndr_heap_t *, netr_info_t *,
@@ -280,7 +280,7 @@ reauth:
*/
if (!did_renego) {
did_renego = B_TRUE;
- netr_invalidate_chain();
+ netr_invalidate_chain(&netr_global_info);
syslog(LOG_ERR, "%s: open failed (%s); "
"renegotiating...",
__func__, xlate_nt_status(status));
@@ -315,7 +315,7 @@ netlogon_logon(smb_logon_t *user_info, smb_token_t *token, smb_domainex_t *di)
"\\\\%s", di->d_dci.dc_name);
if (strncasecmp(netr_global_info.server,
server, strlen(server)) != 0)
- netr_invalidate_chain();
+ netr_invalidate_chain(&netr_global_info);
}
reauth:
@@ -586,7 +586,7 @@ netr_server_samlogon(mlsvc_handle_t *netr_handle, netr_info_t *netr_info,
rc = ndr_rpc_call(netr_handle, opnum, rpc_arg);
if (rc != 0) {
- bzero(netr_info, sizeof (netr_info_t));
+ netr_invalidate_chain(netr_info);
status = NT_STATUS_INVALID_PARAMETER;
} else if (*rpc_status != 0) {
status = NT_SC_VALUE(*rpc_status);
@@ -774,7 +774,7 @@ netr_validate_chain(netr_info_t *netr_info, struct netr_authenticator *auth)
* If the validation fails, destroy the credential chain.
* This should trigger a new authentication chain.
*/
- bzero(netr_info, sizeof (netr_info_t));
+ netr_invalidate_chain(netr_info);
return (NT_STATUS_INSUFFICIENT_LOGON_INFO);
}
@@ -784,7 +784,7 @@ netr_validate_chain(netr_info_t *netr_info, struct netr_authenticator *auth)
* If the validation fails, destroy the credential chain.
* This should trigger a new authentication chain.
*/
- bzero(netr_info, sizeof (netr_info_t));
+ netr_invalidate_chain(netr_info);
result = NT_STATUS_UNSUCCESSFUL;
} else {
/*
@@ -807,9 +807,18 @@ netr_validate_chain(netr_info_t *netr_info, struct netr_authenticator *auth)
* on the next attempt.
*/
static void
-netr_invalidate_chain(void)
+netr_invalidate_chain(netr_info_t *netr_info)
{
- netr_global_info.flags &= ~NETR_FLG_VALID;
+ if ((netr_info->flags & NETR_FLG_VALID) == 0)
+ return;
+
+ netr_info->flags &= ~NETR_FLG_VALID;
+ explicit_bzero(&netr_info->session_key,
+ sizeof (netr_info->session_key));
+ explicit_bzero(&netr_info->client_credential,
+ sizeof (netr_info->client_credential));
+ explicit_bzero(&netr_info->server_credential,
+ sizeof (netr_info->server_credential));
}
/*
diff --git a/usr/src/man/man5/nfs.5 b/usr/src/man/man5/nfs.5
index d53d7bfe98..3788ac5f82 100644
--- a/usr/src/man/man5/nfs.5
+++ b/usr/src/man/man5/nfs.5
@@ -19,8 +19,9 @@
.\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 2016 Nexenta Systems, Inc.
.\" Copyright 2020 Joyent, Inc.
+.\" Copyright 2022 RackTop Systems.
.\"
-.Dd November 22, 2021
+.Dd September 15, 2022
.Dt NFS 5
.Os
.Sh NAME
@@ -195,6 +196,15 @@ should listen.
The default value is
.Li 0 ,
which means it should use a default binding.
+.It Sy mountd_remote_dump Ns = Ns Ar boolean
+Should
+.Nm mountd
+respond to remote
+.Sy MOUNTPROC_DUMP
+queries to read the list of remote mounts.
+The default value is
+.Li false ,
+which means only queries from local host will be allowed.
.It Sy statd_port Ns = Ns Ar num
The IP port number on which
.Nm statd
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_fsctl_odx.c b/usr/src/uts/common/fs/smbsrv/smb2_fsctl_odx.c
index 6a9040a5db..ebf59f6a59 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_fsctl_odx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_fsctl_odx.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018-2021 Tintri by DDN, Inc. All rights reserved.
*/
/*
@@ -82,6 +82,7 @@ typedef struct smb_odx_token {
smb2fid_t tn1_fid;
uint64_t tn1_off;
uint64_t tn1_eof;
+ uint32_t tn1_tid;
} u_tok_native1;
} tok_u;
} smb_odx_token_t;
@@ -136,8 +137,11 @@ uint32_t smb2_odx_write_max = (1<<24); /* 16M */
* needs to be large enough to allow the copy to proceed with
* reasonable efficiency. 1M is currently the largest possible
* block size with ZFS, so that's what we'll use here.
+ *
+ * Actually, limit this to kmem_max_cached, to avoid contention
+ * allocating from kmem_oversize_arena.
*/
-uint32_t smb2_odx_buf_size = (1<<20); /* 1M */
+uint32_t smb2_odx_buf_size = (1<<17); /* 128k */
/*
@@ -352,6 +356,7 @@ done:
tn1->tn1_fid.temporal = ofile->f_fid;
tn1->tn1_off = in_file_off;
tn1->tn1_eof = src_size;
+ tn1->tn1_tid = sr->smb_tid;
}
rc = smb_odx_put_token(fsctl->out_mbc, tok);
@@ -610,8 +615,37 @@ smb2_fsctl_odx_write_native1(smb_request_t *sr,
* but different error code.
*/
tn1 = &tok->tok_u.u_tok_native1;
- src_ofile = smb_ofile_lookup_by_fid(sr,
- (uint16_t)tn1->tn1_fid.temporal);
+
+ /*
+ * If the source ofile came from another tree, we need to
+ * get the other tree and use it for the fid lookup.
+ * Do that by temporarily changing sr->tid_tree around
+ * the call to smb_ofile_lookup_by_fid().
+ */
+ if (tn1->tn1_tid != sr->smb_tid) {
+ smb_tree_t *saved_tree;
+ smb_tree_t *src_tree;
+
+ src_tree = smb_session_lookup_tree(sr->session,
+ (uint16_t)tn1->tn1_tid);
+ if (src_tree == NULL) {
+ status = NT_STATUS_INVALID_TOKEN;
+ goto out;
+ }
+
+ saved_tree = sr->tid_tree;
+ sr->tid_tree = src_tree;
+
+ src_ofile = smb_ofile_lookup_by_fid(sr,
+ (uint16_t)tn1->tn1_fid.temporal);
+
+ sr->tid_tree = saved_tree;
+ smb_tree_release(src_tree);
+ } else {
+ src_ofile = smb_ofile_lookup_by_fid(sr,
+ (uint16_t)tn1->tn1_fid.temporal);
+ }
+
if (src_ofile == NULL ||
src_ofile->f_persistid != tn1->tn1_fid.persistent) {
status = NT_STATUS_INVALID_TOKEN;
@@ -773,11 +807,12 @@ smb_odx_get_token_native1(mbuf_chain_t *mbc, struct tok_native1 *tn1)
int rc;
rc = smb_mbc_decodef(
- mbc, "qqqq",
+ mbc, "qqqql",
&tn1->tn1_fid.persistent,
&tn1->tn1_fid.temporal,
&tn1->tn1_off,
- &tn1->tn1_eof);
+ &tn1->tn1_eof,
+ &tn1->tn1_tid);
return (rc);
}
@@ -839,11 +874,12 @@ smb_odx_put_token_native1(mbuf_chain_t *mbc, struct tok_native1 *tn1)
int rc;
rc = smb_mbc_encodef(
- mbc, "qqqq",
+ mbc, "qqqql",
tn1->tn1_fid.persistent,
tn1->tn1_fid.temporal,
tn1->tn1_off,
- tn1->tn1_eof);
+ tn1->tn1_eof,
+ tn1->tn1_tid);
return (rc);
}