diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/fs.d/nfs/mountd/Makefile | 4 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/nfs/mountd/mountd.c | 86 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/nfs/svc/server.xml | 2 | ||||
-rw-r--r-- | usr/src/lib/libshare/nfs/libshare_nfs.c | 9 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c | 30 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c | 27 | ||||
-rw-r--r-- | usr/src/man/man5/nfs.5 | 12 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_fsctl_odx.c | 52 |
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); } |