1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
22fd9ee8b5Sjoyce mcintosh  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
231123b345SMatt Barden  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw #include <sys/types.h>
27da6c28aaSamw #include <sys/stat.h>
28da6c28aaSamw #include <sys/uio.h>
29da6c28aaSamw #include <sys/statvfs.h>
30da6c28aaSamw #include <sys/vnode.h>
31da6c28aaSamw #include <sys/thread.h>
32da6c28aaSamw #include <sys/pathname.h>
33da6c28aaSamw #include <sys/cred.h>
34da6c28aaSamw #include <sys/extdirent.h>
35dc20a302Sas #include <sys/nbmlock.h>
36dc20a302Sas #include <sys/share.h>
37dc20a302Sas #include <sys/fcntl.h>
38faa1795aSjb #include <nfs/lm.h>
3955bf511dSas 
40bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
41da6c28aaSamw #include <smbsrv/string.h>
42bbf6f00cSJordan Brown #include <smbsrv/smb_vops.h>
43da6c28aaSamw #include <smbsrv/smb_fsops.h>
4455bf511dSas 
458b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /*
468b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * CATIA support
478b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *
488b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * CATIA V4 is a UNIX product and uses characters in filenames that
498b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * are considered invalid by Windows. CATIA V5 is available on both
508b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * UNIX and Windows.  Thus, as CATIA customers migrate from V4 to V5,
518b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * some V4 files could become inaccessible to windows clients if the
528b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * filename contains the characters that are considered illegal in
538b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Windows.  In order to address this issue an optional character
548b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * translation is applied to filenames at the smb_vop interface.
558b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *
568b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Character Translation Table
578b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * ----------------------------------
588b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Unix-char (v4) | Windows-char (v5)
598b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * ----------------------------------
608b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        *       |  0x00a4  Currency Sign
618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        |       |  0x00a6  Broken Bar
628b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        "       |  0x00a8  Diaeresis
638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        <       |  0x00ab  Left-Pointing Double Angle Quotation Mark
648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        >       |  0x00bb  Right-Pointing Double Angle Quotation Mark
658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        ?       |  0x00bf  Inverted Question mark
668b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        :       |  0x00f7  Division Sign
678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        /       |  0x00f8  Latin Small Letter o with stroke
688b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *        \       |  0x00ff  Latin Small Letter Y with Diaeresis
698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *
708b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *
718b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Two lookup tables are used to perform the character translation:
728b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *
738b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * smb_catia_v5_lookup - provides the mapping between UNIX ASCII (v4)
748b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * characters and equivalent or translated wide characters.
758b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * It is indexed by the decimal value of the ASCII character (0-127).
768b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  *
778b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * smb_catia_v4_lookup - provides the mapping between wide characters
788b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * in the range from 0x00A4 to 0x00FF and their UNIX (v4) equivalent
798b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * (in wide character format).  It is indexed by the decimal value of
808b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * the wide character (164-255) with an offset of -164.
818b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * If this translation produces a filename containing a '/' create, mkdir
828b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * or rename (to the '/' name)  operations will not be permitted. It is
838b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * not valid to create a filename with a '/' in it. However, if such a
848b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * file already exists other operations (e.g, lookup, delete, rename)
858b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * are permitted on it.
868b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  */
878b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
888b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /* number of characters mapped */
898b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_NUM_MAPS		9
908b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
918b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /* Windows Characters used in special character mapping */
928b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_CURRENCY		0x00a4
938b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_BROKEN_BAR	0x00a6
948b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_DIAERESIS		0x00a8
958b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_LEFT_ANGLE	0x00ab
968b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_RIGHT_ANGLE	0x00bb
978b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_INVERTED_QUESTION	0x00bf
988b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_DIVISION		0x00f7
998b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_LATIN_O		0x00f8
1008b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_WIN_LATIN_Y		0x00ff
1018b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
1028b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_V4_LOOKUP_LOW		SMB_CATIA_WIN_CURRENCY
1038b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_V4_LOOKUP_UPPER	SMB_CATIA_WIN_LATIN_Y
1048b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_V4_LOOKUP_MAX		\
1058b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	(SMB_CATIA_V4_LOOKUP_UPPER - SMB_CATIA_V4_LOOKUP_LOW + 1)
1068b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CATIA_V5_LOOKUP_MAX		0x0080
1078b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
1088b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States typedef struct smb_catia_map
1098b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States {
1108b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	unsigned char unixchar;	/* v4 */
111bbf6f00cSJordan Brown 	smb_wchar_t winchar;	/* v5 */
1128b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } smb_catia_map_t;
1138b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
1148622ec45SGordon Ross smb_catia_map_t const catia_maps[SMB_CATIA_NUM_MAPS] =
1158b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States {
1168b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'"',  SMB_CATIA_WIN_DIAERESIS},
1178b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'*',  SMB_CATIA_WIN_CURRENCY},
1188b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{':',  SMB_CATIA_WIN_DIVISION},
1198b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'<',  SMB_CATIA_WIN_LEFT_ANGLE},
1208b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'>',  SMB_CATIA_WIN_RIGHT_ANGLE},
1218b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'?',  SMB_CATIA_WIN_INVERTED_QUESTION},
1228b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'\\', SMB_CATIA_WIN_LATIN_Y},
1238b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'/',  SMB_CATIA_WIN_LATIN_O},
1248b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	{'|',  SMB_CATIA_WIN_BROKEN_BAR}
1258b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States };
1268b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
127bbf6f00cSJordan Brown static smb_wchar_t smb_catia_v5_lookup[SMB_CATIA_V5_LOOKUP_MAX];
128bbf6f00cSJordan Brown static smb_wchar_t smb_catia_v4_lookup[SMB_CATIA_V4_LOOKUP_MAX];
1298b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
1307f667e74Sjose borrego static void smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr);
1317f667e74Sjose borrego static void smb_sa_to_va_mask(uint_t sa_mask, uint_t *va_maskp);
1327f667e74Sjose borrego static callb_cpr_t *smb_lock_frlock_callback(flk_cb_when_t, void *);
1338b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static void smb_vop_catia_init();
1348c10a865Sas 
135dc20a302Sas extern sysid_t lm_alloc_sysidt();
136dc20a302Sas 
137da6c28aaSamw #define	SMB_AT_MAX	16
1388622ec45SGordon Ross static const uint_t smb_attrmap[SMB_AT_MAX] = {
139da6c28aaSamw 	0,
140da6c28aaSamw 	AT_TYPE,
141da6c28aaSamw 	AT_MODE,
142da6c28aaSamw 	AT_UID,
143da6c28aaSamw 	AT_GID,
144da6c28aaSamw 	AT_FSID,
145da6c28aaSamw 	AT_NODEID,
146da6c28aaSamw 	AT_NLINK,
147da6c28aaSamw 	AT_SIZE,
148da6c28aaSamw 	AT_ATIME,
149da6c28aaSamw 	AT_MTIME,
150da6c28aaSamw 	AT_CTIME,
151da6c28aaSamw 	AT_RDEV,
152da6c28aaSamw 	AT_BLKSIZE,
153da6c28aaSamw 	AT_NBLOCKS,
154da6c28aaSamw 	AT_SEQ
155da6c28aaSamw };
156da6c28aaSamw 
157faa1795aSjb static boolean_t	smb_vop_initialized = B_FALSE;
158faa1795aSjb caller_context_t	smb_ct;
159faa1795aSjb 
160dc20a302Sas /*
161faa1795aSjb  * smb_vop_init
162faa1795aSjb  *
163faa1795aSjb  * This function is not multi-thread safe. The caller must make sure only one
164faa1795aSjb  * thread makes the call.
165dc20a302Sas  */
166faa1795aSjb int
smb_vop_init(void)167faa1795aSjb smb_vop_init(void)
168faa1795aSjb {
169faa1795aSjb 	if (smb_vop_initialized)
170faa1795aSjb 		return (0);
171faa1795aSjb 	/*
172faa1795aSjb 	 * The caller_context will be used primarily for range locking.
173faa1795aSjb 	 * Since the CIFS server is mapping its locks to POSIX locks,
174faa1795aSjb 	 * only one pid is used for operations originating from the
175faa1795aSjb 	 * CIFS server (to represent CIFS in the VOP_FRLOCK routines).
1768622ec45SGordon Ross 	 *
1778622ec45SGordon Ross 	 * XXX: Should smb_ct be per-zone?
178faa1795aSjb 	 */
179faa1795aSjb 	smb_ct.cc_sysid = lm_alloc_sysidt();
180faa1795aSjb 	if (smb_ct.cc_sysid == LM_NOSYSID)
181faa1795aSjb 		return (ENOMEM);
182dc20a302Sas 
183faa1795aSjb 	smb_ct.cc_caller_id = fs_new_caller_id();
1846537f381Sas 	smb_ct.cc_pid = IGN_PID;
185faa1795aSjb 	smb_ct.cc_flags = 0;
1868b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_vop_catia_init();
187faa1795aSjb 
188faa1795aSjb 	smb_vop_initialized = B_TRUE;
189faa1795aSjb 	return (0);
190faa1795aSjb }
191dc20a302Sas 
192dc20a302Sas /*
193faa1795aSjb  * smb_vop_fini
194dc20a302Sas  *
195faa1795aSjb  * This function is not multi-thread safe. The caller must make sure only one
196faa1795aSjb  * thread makes the call.
197dc20a302Sas  */
198dc20a302Sas void
smb_vop_fini(void)199faa1795aSjb smb_vop_fini(void)
200dc20a302Sas {
201faa1795aSjb 	if (!smb_vop_initialized)
202faa1795aSjb 		return;
203dc20a302Sas 
204faa1795aSjb 	lm_free_sysidt(smb_ct.cc_sysid);
2056537f381Sas 	smb_ct.cc_pid = IGN_PID;
206faa1795aSjb 	smb_ct.cc_sysid = LM_NOSYSID;
207faa1795aSjb 	smb_vop_initialized = B_FALSE;
208dc20a302Sas }
209dc20a302Sas 
210faa1795aSjb /*
211faa1795aSjb  * The smb_ct will be used primarily for range locking.
212faa1795aSjb  * Since the CIFS server is mapping its locks to POSIX locks,
213faa1795aSjb  * only one pid is used for operations originating from the
214faa1795aSjb  * CIFS server (to represent CIFS in the VOP_FRLOCK routines).
215faa1795aSjb  */
216da6c28aaSamw int
smb_vop_open(vnode_t ** vpp,int mode,cred_t * cred)217dc20a302Sas smb_vop_open(vnode_t **vpp, int mode, cred_t *cred)
218da6c28aaSamw {
219dc20a302Sas 	return (VOP_OPEN(vpp, mode, cred, &smb_ct));
220da6c28aaSamw }
221da6c28aaSamw 
222c8ec8eeaSjose borrego void
smb_vop_close(vnode_t * vp,int mode,cred_t * cred)223dc20a302Sas smb_vop_close(vnode_t *vp, int mode, cred_t *cred)
224da6c28aaSamw {
225c8ec8eeaSjose borrego 	(void) VOP_CLOSE(vp, mode, 1, (offset_t)0, cred, &smb_ct);
226da6c28aaSamw }
227da6c28aaSamw 
2288c10a865Sas int
smb_vop_other_opens(vnode_t * vp,int mode)2298c10a865Sas smb_vop_other_opens(vnode_t *vp, int mode)
2308c10a865Sas {
2318c10a865Sas 	return (((mode & FWRITE) && vn_has_other_opens(vp, V_WRITE)) ||
2328c10a865Sas 	    (((mode & FWRITE) == 0) && vn_is_opened(vp, V_WRITE)) ||
2338c10a865Sas 	    ((mode & FREAD) && vn_has_other_opens(vp, V_READ)) ||
2348c10a865Sas 	    (((mode & FREAD) == 0) && vn_is_opened(vp, V_READ)) ||
2358c10a865Sas 	    vn_is_mapped(vp, V_RDORWR));
2368c10a865Sas }
2378c10a865Sas 
238da6c28aaSamw /*
239da6c28aaSamw  * The smb_vop_* functions have minimal knowledge of CIFS semantics and
240da6c28aaSamw  * serve as an interface to the VFS layer.
241da6c28aaSamw  *
242da6c28aaSamw  * Only smb_fsop_* layer functions should call smb_vop_* layer functions.
243da6c28aaSamw  * (Higher-level CIFS service code should never skip the smb_fsop_* layer
244da6c28aaSamw  * to call smb_vop_* layer functions directly.)
245da6c28aaSamw  */
246da6c28aaSamw 
247da6c28aaSamw /*
248