Print this page
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)
NEX-2807 Restoring previous versions from snapshots doesn't work with nested folders.
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-3611 CLONE NEX-3550 Replace smb2_enable with max_protocol
Reviewed by: Yuri Pankov <Yuri.Pankov@nexenta.com>
SMB-136 Snapshots not visible in Windows previous versions
SMB-65 SMB server in non-global zones (use zone_kcred())
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).

*** 18,28 **** * * CDDL HEADER END */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* * Volume Copy Shadow Services (VSS) provides a way for users to * restore/recover deleted files/directories. --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ /* * Volume Copy Shadow Services (VSS) provides a way for users to * restore/recover deleted files/directories.
*** 39,49 **** * in the snapshot. */ #include <smbsrv/smb_kproto.h> #include <smbsrv/string.h> ! #include <smbsrv/winioctl.h> #include <smbsrv/smb_door.h> /* Size of the token on the wire due to encoding */ #define SMB_VSS_GMT_NET_SIZE(sr) (smb_ascii_or_unicode_null_len(sr) * \ SMB_VSS_GMT_SIZE) --- 39,49 ---- * in the snapshot. */ #include <smbsrv/smb_kproto.h> #include <smbsrv/string.h> ! #include <smb/winioctl.h> #include <smbsrv/smb_door.h> /* Size of the token on the wire due to encoding */ #define SMB_VSS_GMT_NET_SIZE(sr) (smb_ascii_or_unicode_null_len(sr) * \ SMB_VSS_GMT_SIZE)
*** 76,97 **** smb_vss_enum_snapshots(smb_request_t *sr, smb_fsctl_t *fsctl) { uint32_t count = 0; char *root_path; uint32_t status = NT_STATUS_SUCCESS; - smb_node_t *tnode; smb_gmttoken_response_t snaps; ! ASSERT(sr->tid_tree); ! ASSERT(sr->tid_tree->t_snode); if (fsctl->MaxOutputResp < SMB_VSS_COUNT_SIZE) return (NT_STATUS_INVALID_PARAMETER); ! tnode = sr->tid_tree->t_snode; root_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); ! if (smb_node_getmntpath(tnode, root_path, MAXPATHLEN) != 0) return (NT_STATUS_INVALID_PARAMETER); if (fsctl->MaxOutputResp == SMB_VSS_COUNT_SIZE) { count = smb_vss_get_count(sr->tid_tree, root_path); if (smb_mbc_encodef(fsctl->out_mbc, "lllw", count, 0, --- 76,101 ---- smb_vss_enum_snapshots(smb_request_t *sr, smb_fsctl_t *fsctl) { uint32_t count = 0; char *root_path; uint32_t status = NT_STATUS_SUCCESS; smb_gmttoken_response_t snaps; ! ASSERT(sr->fid_ofile); ! ASSERT(sr->fid_ofile->f_node); if (fsctl->MaxOutputResp < SMB_VSS_COUNT_SIZE) return (NT_STATUS_INVALID_PARAMETER); ! /* ! * smbd will find the root of the lowest filesystem from mntpath of a ! * file by comparing it agaisnt mnttab, repeatedly removing components ! * until one matches. ! */ root_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); ! if (smb_node_getmntpath(sr->fid_ofile->f_node, root_path, ! MAXPATHLEN) != 0) return (NT_STATUS_INVALID_PARAMETER); if (fsctl->MaxOutputResp == SMB_VSS_COUNT_SIZE) { count = smb_vss_get_count(sr->tid_tree, root_path); if (smb_mbc_encodef(fsctl->out_mbc, "lllw", count, 0,
*** 116,190 **** /* * sr - the request info, used to find root of dataset, * unicode or ascii, where the share is rooted in the * dataset - * root_node - root of the share * cur_node - where in the share for the command - * buf - is the path for the command to be processed - * returned without @GMT if processed * vss_cur_node - returned value for the snapshot version * of the cur_node ! * vss_root_node - returned value for the snapshot version ! * of the root_node * * This routine is the processing for handling the * SMB_FLAGS2_REPARSE_PATH bit being set in the smb header. * * By using the cur_node passed in, a new node is found or * created that is the same place in the directory tree, but ! * in the snapshot. We also use root_node to do the same for ! * the root. ! * Once the new smb node is found, the path is modified by ! * removing the @GMT token from the path in the buf. */ int ! smb_vss_lookup_nodes(smb_request_t *sr, smb_node_t *root_node, ! smb_node_t *cur_node, char *buf, smb_node_t **vss_cur_node, ! smb_node_t **vss_root_node) { smb_arg_open_t *op = &sr->arg.open; - smb_node_t *tnode; char *snapname, *path; - char *gmttoken; - char gmttok_buf[SMB_VSS_GMT_SIZE]; vnode_t *fsrootvp = NULL; time_t toktime; int err = 0; - boolean_t smb1; if (sr->tid_tree == NULL) return (ESTALE); ! tnode = sr->tid_tree->t_snode; ! ! ASSERT(tnode); ! ASSERT(tnode->vp); ! ASSERT(tnode->vp->v_vfsp); ! ! smb1 = (sr->session->dialect < SMB_VERS_2_BASE); ! if (smb1) { ! const char *p; ! ! /* get gmttoken from buf */ ! if ((p = smb_vss_find_gmttoken(buf)) == NULL) ! return (ENOENT); ! ! bcopy(p, gmttok_buf, SMB_VSS_GMT_SIZE); ! gmttok_buf[SMB_VSS_GMT_SIZE - 1] = '\0'; ! gmttoken = gmttok_buf; toktime = 0; } else { /* SMB2 and later */ - gmttoken = NULL; toktime = op->timewarp.tv_sec; } path = smb_srm_alloc(sr, MAXPATHLEN); snapname = smb_srm_alloc(sr, MAXPATHLEN); ! err = smb_node_getmntpath(tnode, path, MAXPATHLEN); if (err != 0) return (err); /* * Find the corresponding snapshot name. If snapname is --- 120,166 ---- /* * sr - the request info, used to find root of dataset, * unicode or ascii, where the share is rooted in the * dataset * cur_node - where in the share for the command * vss_cur_node - returned value for the snapshot version * of the cur_node ! * gmttoken - if SMB1, the gmttoken to be used to find the snapshot. ! * Otherwise, NULL. * * This routine is the processing for handling the * SMB_FLAGS2_REPARSE_PATH bit being set in the smb header. * * By using the cur_node passed in, a new node is found or * created that is the same place in the directory tree, but ! * in the snapshot. */ int ! smb_vss_lookup_nodes(smb_request_t *sr, smb_node_t *cur_node, ! smb_node_t **vss_cur_node, char *gmttoken) { smb_arg_open_t *op = &sr->arg.open; char *snapname, *path; vnode_t *fsrootvp = NULL; time_t toktime; int err = 0; if (sr->tid_tree == NULL) return (ESTALE); ! if (gmttoken != NULL) { toktime = 0; } else { /* SMB2 and later */ toktime = op->timewarp.tv_sec; } path = smb_srm_alloc(sr, MAXPATHLEN); snapname = smb_srm_alloc(sr, MAXPATHLEN); ! err = smb_node_getmntpath(cur_node, path, MAXPATHLEN); if (err != 0) return (err); /* * Find the corresponding snapshot name. If snapname is
*** 195,224 **** snapname); if (*snapname == '\0') return (ENOENT); /* find snapshot nodes */ ! err = VFS_ROOT(tnode->vp->v_vfsp, &fsrootvp); if (err != 0) return (err); - /* find snapshot node corresponding to root_node */ - err = smb_vss_lookup_node(sr, root_node, fsrootvp, - snapname, cur_node, vss_root_node); - if (err == 0) { /* find snapshot node corresponding to cur_node */ err = smb_vss_lookup_node(sr, cur_node, fsrootvp, snapname, cur_node, vss_cur_node); - if (err != 0) - smb_node_release(*vss_root_node); - } VN_RELE(fsrootvp); - if (smb1) - smb_vss_remove_first_token_from_path(buf); - return (err); } /* * Find snapshot node corresponding to 'node', and return it in --- 171,190 ---- snapname); if (*snapname == '\0') return (ENOENT); /* find snapshot nodes */ ! err = VFS_ROOT(cur_node->vp->v_vfsp, &fsrootvp); if (err != 0) return (err); /* find snapshot node corresponding to cur_node */ err = smb_vss_lookup_node(sr, cur_node, fsrootvp, snapname, cur_node, vss_cur_node); VN_RELE(fsrootvp); return (err); } /* * Find snapshot node corresponding to 'node', and return it in
*** 439,444 **** --- 405,427 ---- request.gts_toktime = toktime; (void) smb_kdoor_upcall(tree->t_server, SMB_DR_VSS_MAP_GMTTOKEN, &request, smb_gmttoken_snapname_xdr, &result, smb_string_xdr); + } + + int + smb_vss_extract_gmttoken(char *buf, char *gmttoken) + { + const char *p; + + /* get gmttoken from buf */ + if ((p = smb_vss_find_gmttoken(buf)) == NULL) + return (ENOENT); + + bcopy(p, gmttoken, SMB_VSS_GMT_SIZE); + gmttoken[SMB_VSS_GMT_SIZE - 1] = '\0'; + + smb_vss_remove_first_token_from_path(buf); + + return (0); }