1/*
2 * Copyright (c) 2000-2001, Boris Popov
3 * All rights reserved.
4 *
5 * Portions Copyright (C) 2001 - 2014 Apple Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *    This product includes software developed by Boris Popov.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36#ifndef _SMBFS_SMBFS_H_
37#define _SMBFS_SMBFS_H_
38
39#include <sys/kdebug.h>
40#include <netinet/in.h>
41#include <netsmb/netbios.h>
42
43#define SMBFS_VERMAJ	3
44#define SMBFS_VERMIN	0000
45#define SMBFS_VERSION	(SMBFS_VERMAJ*100000 + SMBFS_VERMIN)
46#define	SMBFS_VFSNAME	"smbfs"
47#define SMBFS_LANMAN	"SMBFS 3.0.0"	/* Needs to match SMBFS_VERSION */
48#define SMBFS_NATIVEOS	"Mac OS X 10.10"	/* Needs to match current OS version major number only */
49#define SMBFS_SLASH_TONAME "/Volumes/0x2f"
50
51#define	SMBFS_MAXPATHCOMP	256	/* maximum number of path components */
52
53#include <sys/mount.h>
54
55#define SMB_STREAMS_ON	".com.apple.smb.streams.on"
56#define SMB_STREAMS_OFF	".com.apple.smb.streams.off"
57
58#define SMB_MAX_UNIQUE_ID	128 + MAXPATHLEN + (int32_t)sizeof(struct sockaddr_storage)  /* Share name, path, sockaddr */
59
60
61#define kGuestAccountName	"GUEST"
62#define kGuestPassword		""
63
64
65struct ByteRangeLockPB {
66	int64_t	offset;		/* offset to first byte to lock */
67	int64_t	length;		/* nbr of bytes to lock */
68	uint64_t	retRangeStart;	/* nbr of first byte locked if successful */
69	uint8_t	unLockFlag;	/* 1 = unlock, 0 = lock */
70	uint8_t	startEndFlag;	/* 1 = rel to end of fork, 0 = rel to start */
71};
72
73struct ByteRangeLockPB2 {
74	int64_t	offset;		/* offset to first byte to lock */
75	int64_t	length;		/* nbr of bytes to lock */
76	uint64_t	retRangeStart;	/* nbr of first byte locked if successful */
77	uint8_t	unLockFlag;	/* 1 = unlock, 0 = lock */
78	uint8_t	startEndFlag;	/* 1 = rel to end of fork, 0 = rel to start */
79	int32_t		fd;
80};
81
82struct gssdProxyPB
83{
84	uint32_t	mechtype;
85	uint32_t	alignPad1;
86	uint8_t	*intoken;
87	uint32_t	intokenLen;
88	uint32_t	uid;
89	uint8_t	*svc_namestr;
90	uint64_t	verifier;		// inout
91	uint32_t	context;		// inout
92	uint32_t	cred_handle;		// inout
93	uint8_t	*outtoken;		// out
94	uint32_t	outtokenLen;		// inout
95	uint32_t	major_stat;		// out
96	uint32_t	minor_stat;		// out
97};
98
99#ifdef KERNEL
100
101struct user_gssdProxyPB
102{
103	uint32_t	mechtype;
104	user_addr_t	intoken;
105	uint32_t	intokenLen;
106	uint32_t	uid;
107	user_addr_t	svc_namestr;
108	uint64_t	verifier;		// inout
109	uint32_t	context;		// inout
110	uint32_t	cred_handle;		// inout
111	user_addr_t	outtoken;		// out
112	uint32_t	outtokenLen;		// inout
113	uint32_t	major_stat;		// out
114	uint32_t	minor_stat;		// out
115};
116#endif
117
118enum  {
119	kConnectedByUser = 0,
120	kConnectedByGuest = 1,
121	kConnectedByAnonymous = 2,
122	kConnectedByKerberos = 4
123};
124
125/*
126 * We just want to know the type of access used to mount the volume and the
127 * user name used. If not set then the unique_id needs to be set.
128 */
129#define SMBFS_GET_ACCESS_INFO	1
130
131struct UniqueSMBShareID {
132	int32_t		connection_type;
133	int32_t		flags;
134	int32_t		error;
135	int32_t		unique_id_len;
136	unsigned char	unique_id[SMB_MAX_UNIQUE_ID] __attribute((aligned(8)));	/* A set of bytes that uniquely identifies this volume */
137	char		user[SMB_MAXUSERNAMELEN + 1] __attribute((aligned(8)));
138};
139
140#define smbfsByteRangeLock2FSCTL		_IOWR('z', 23, struct ByteRangeLockPB2)
141#define smbfsByteRangeLock2FSCTL_BASECMD	IOCBASECMD(smbfsByteRangeLock2FSCTL)
142
143#define smbfsByteRangeLockFSCTL			_IOWR('z', 17, struct ByteRangeLockPB)
144#define smbfsByteRangeLockFSCTL_BASECMD		IOCBASECMD(smbfsByteRangeLockFSCTL)
145
146#define smbfsUniqueShareIDFSCTL			_IOWR('z', 19, struct UniqueSMBShareID)
147#define smbfsUniqueShareIDFSCTL_BASECMD		IOCBASECMD(smbfsUniqueShareIDFSCTL)
148
149#define smbfsGetVCSockaddrFSCTL			_IOR('z', 20, struct sockaddr_storage)
150#define smbfsGetVCSockaddrFSCTL_BASECMD		IOCBASECMD(smbfsGetVCSockaddrFSCTL)
151
152/* Layout of the mount control block for an smb file system. */
153struct smb_mount_args {
154	int32_t		version;
155	int32_t		dev;
156	int32_t		altflags;
157	int32_t		KernelLogLevel;
158	uid_t		uid;
159	gid_t 		gid;
160	mode_t 		file_mode;
161	mode_t 		dir_mode;
162	uint32_t	path_len;
163	int32_t		unique_id_len;
164	char		path[MAXPATHLEN] __attribute((aligned(8))); /* The starting path they want used for the mount */
165	char		url_fromname[MAXPATHLEN] __attribute((aligned(8))); /* The from name is the url used to mount the volume. */
166	unsigned char	unique_id[SMB_MAX_UNIQUE_ID] __attribute((aligned(8))); /* A set of bytes that uniquely identifies this volume */
167	char		volume_name[MAXPATHLEN] __attribute((aligned(8))); /* The starting path they want used for the mount */
168	uint64_t	ioc_reserved __attribute((aligned(8))); /* Force correct size always */
169	int32_t		max_resp_timeout;
170};
171
172#define SMBFS_SYSCTL_REMOUNT 1
173#define SMBFS_SYSCTL_REMOUNT_INFO 2
174#define SMBFS_SYSCTL_GET_SERVER_SHARE 3
175
176#define REMOUNT_INFO_VERSION	1
177
178struct smb_remount_info {
179	uint32_t	version;
180	uint32_t	mntAuthFlags;
181	uid_t		mntOwner;
182	uid_t		mntGroup;
183	uint32_t	mntDeadTimer;
184	uint32_t	mntClientPrincipalNameType;
185	char		mntClientPrincipalName[MAXPATHLEN] __attribute((aligned(8)));
186	char		mntURL[MAXPATHLEN] __attribute((aligned(8)));
187};
188
189#ifdef KERNEL
190
191/* The items the mount point keeps in memory */
192struct smbfs_args {
193	int32_t		altflags;
194	uid_t		uid;
195	gid_t 		gid;
196	guid_t		uuid;		/* The UUID of the user that mounted the volume */
197	mode_t 		file_mode;
198	mode_t 		dir_mode;
199	size_t		path_len;	/* Must be less than MAXPATHLEN and does not count the null byte */
200	char		*path;		/* The starting path they want to use with this mounted volume */
201	int32_t		unique_id_len;
202	unsigned char	*unique_id;	/* A set of bytes that uniquely identifies this volume */
203	char		*volume_name;
204};
205
206#ifdef MALLOC_DECLARE
207MALLOC_DECLARE(M_SMBFSMNT);
208#endif
209
210struct smbnode;
211struct smb_share;
212struct u_cred;
213struct vnop_ioctl_args;
214struct buf;
215struct smbfs_notify_change;
216
217/*
218 * SM_MAX_STATFSTIME is the maximum time to cache statfs data. Since this
219 * should be a fast call on the server, the time the data cached is short.
220 * That lets the cache handle bursts of statfs() requests without generating
221 * lots of network traffic.
222 */
223#define SM_MAX_STATFSTIME 2
224
225/* Mask values for smbmount structure sm_status field */
226#define SM_STATUS_STATFS	0x00000001 /* statfs is in progress */
227#define SM_STATUS_STATFS_WANTED	0x00000002 /* statfs wakeup is wanted */
228#define SM_STATUS_DOWN		0x00000004 /* this mount is not responding */
229#define SM_STATUS_DEAD		0x00000010 /* connection gone - unmount this */
230#define SM_STATUS_REMOUNT	0x00000020 /* remount inprogress */
231#define SM_STATUS_UPDATED	0x00000040 /* Remounted with new server/share */
232/*
233 * Some servers do not support all the info levels on Trans2 calls. Most systems do not care if you
234 * use a file descriptor or a path name to do a get or set info call. Seems NetApp requires an file descriptor when
235 * setting the time on a file.
236 */
237#define MNT_REQUIRES_FILEID_FOR_TIME		0x0001	/* Setting time requires a file descriptor */
238#define MNT_MAPS_NETWORK_LOCAL_USER		0x0002 /* Map  Network User <==> Local User */
239#define MNT_IS_SFM_VOLUME				0x0004	/* We mount a Service for Macintosh Volume */
240#define MNT_SUPPORTS_REPARSE_SYMLINKS		0x0008
241
242/*
243 * Bit definitions for the svrmsg_pending field in the smbmount structure
244 */
245#define SVRMSG_RCVD_GOING_DOWN	0x0000000000000001
246#define SVRMSG_RCVD_SHUTDOWN_CANCEL	0x0000000000000002
247
248struct smbmount {
249	uint64_t		ntwrk_uid;
250	uint64_t		ntwrk_gid;
251	uint32_t		ntwrk_cnt_gid;
252	uint64_t		*ntwrk_gids;
253	ntsid_t			*ntwrk_sids;
254	uint32_t		ntwrk_sids_cnt;
255	struct smbfs_args	sm_args;
256	struct mount * 		sm_mp;
257	vnode_t			sm_rvp;
258	uint64_t		sm_root_ino;
259	struct smb_share * 	sm_share;
260	lck_rw_t		sm_rw_sharelock;
261	int			sm_flags;
262	lck_mtx_t		*sm_hashlock;
263	LIST_HEAD(smbnode_hashhead, smbnode) *sm_hash;
264	u_long			sm_hashlen;
265	uint32_t		sm_status; /* status bits for this mount */
266	time_t			sm_statfstime; /* sm_statfsbuf cache time */
267	lck_mtx_t		sm_statfslock; /* sm_statsbuf lock */
268	struct vfsstatfs	sm_statfsbuf; /* cached statfs data */
269	lck_mtx_t		sm_reclaim_lock; /* mount reclaim lock */
270	void			*notify_thread;	/* pointer to the notify thread structure */
271	int32_t			tooManyNotifies;
272	lck_mtx_t		sm_svrmsg_lock;		/* protects svrmsg fields */
273	uint64_t		sm_svrmsg_pending;	/* svrmsg replies pending (bits defined above) */
274	uint32_t		sm_svrmsg_shutdown_delay;  /* valid when SVRMSG_GOING_DOWN is set */
275};
276
277#define VFSTOSMBFS(mp)		((struct smbmount *)(vfs_fsprivate(mp)))
278#define	VTOSMBFS(vp)		(VFSTOSMBFS(vnode_mount(vp)))
279
280#define SMB_SYMMAGICLEN (4+1) /* includes a '\n' seperator */
281extern char smb_symmagic[];
282#define SMB_SYMLENLEN (4+1) /* includes a '\n' seperator */
283#define SMB_SYMMD5LEN (32+1) /* includes a '\n' seperator */
284#define SMB_SYMHDRLEN (SMB_SYMMAGICLEN + SMB_SYMLENLEN + SMB_SYMMD5LEN)
285#define SMB_SYMLEN (SMB_SYMHDRLEN + MAXPATHLEN)
286
287#define CON_FILENAME(nn, nl) \
288	(((nl) >= 3) && \
289	(((*(nn) == 'c') || (*(nn) == 'C')) &&	\
290	((*((nn)+1) == 'o') || (*((nn)+1) == 'O')) && \
291	((*((nn)+2) == 'n') || (*((nn)+2) == 'N'))))
292
293/*
294 * internal versions of VOPs
295 */
296int smbfs_close(struct smb_share *share, vnode_t vp, int openMode,
297		vfs_context_t context);
298int smbfs_open(struct smb_share *share, vnode_t vp, int mode,
299	       vfs_context_t context);
300
301int smbfs_update_cache(struct smb_share *share, vnode_t vp,
302		       struct vnode_attr *vap, vfs_context_t context);
303int smbfs_fsync(struct smb_share *share, vnode_t vp, int waitfor, int ubc_flags,
304		vfs_context_t context);
305
306/*
307 * Notify change routines
308 */
309void smbfs_notify_change_create_thread(struct smbmount *smp);
310void smbfs_notify_change_destroy_thread(struct smbmount *smp);
311int smbfs_start_change_notify(struct smb_share *share, struct smbnode *np,
312			      vfs_context_t context, int *releaseLock);
313int smbfs_start_svrmsg_notify(struct smbmount *smp);
314int smbfs_stop_change_notify(struct smb_share *share, struct smbnode *np,
315			     int forceClose, vfs_context_t context, int *releaseLock);
316int smbfs_stop_svrmsg_notify(struct smbmount *smp);
317void smbfs_restart_change_notify(struct smb_share *share, struct smbnode *np,
318				 vfs_context_t context);
319
320#define SMB_IOMIN (1024 * 1024)
321#define SMB_IOMAXCACHE (SMB_IOMIN * 4)
322#define SMB_IOMAX ((size_t)MAX_UPL_SIZE * PAGE_SIZE)
323
324/*
325* KERNEL_DEBUG related definitions for SMB.
326*
327* NOTE: The Class DBG_FSYSTEM = 3, and Subclass DBG_SMB = 0xA, so these
328* debug codes are of the form 0x030Annnn.
329*/
330#define DBG_SMB     0xA     /* SMB-specific events; see the smb project */
331
332#define SMB_DBG_CODE(code)    FSDBG_CODE(DBG_SMB, code)
333
334/* example usage */
335//SMB_LOG_KTRACE(SMB_DBG_MOUNT | DBG_FUNC_START, 0, 0, 0, 0, 0);
336//SMB_LOG_KTRACE(SMB_DBG_MOUNT | DBG_FUNC_END, error, 0, 0, 0, 0);
337//SMB_LOG_KTRACE(SMB_DBG_MOUNT | DBG_FUNC_NONE, 0xabc001, error, 0, 0, 0);
338
339enum {
340        /* VFS OPs */
341        SMB_DBG_MOUNT                     = SMB_DBG_CODE(0),    /* 0x030A0000 */
342        SMB_DBG_UNMOUNT                   = SMB_DBG_CODE(1),    /* 0x030A0004 */
343        SMB_DBG_ROOT                      = SMB_DBG_CODE(2),    /* 0x030A0008 */
344        SMB_DBG_VFS_GETATTR               = SMB_DBG_CODE(3),    /* 0x030A000C */
345        SMB_DBG_SYNC                      = SMB_DBG_CODE(4),    /* 0x030A0010 */
346        SMB_DBG_VGET                      = SMB_DBG_CODE(5),    /* 0x030A0014 */
347        SMB_DBG_SYSCTL                    = SMB_DBG_CODE(6),    /* 0x030A0018 */
348
349        /* VFS VNODE OPs */
350        SMB_DBG_ADVLOCK                   = SMB_DBG_CODE(7),    /* 0x030A001C */
351        SMB_DBG_CLOSE                     = SMB_DBG_CODE(8),    /* 0x030A0020 */
352        SMB_DBG_CREATE                    = SMB_DBG_CODE(9),    /* 0x030A0024 */
353        SMB_DBG_FSYNC                     = SMB_DBG_CODE(10),   /* 0x030A0028 */
354        SMB_DBG_GET_ATTR                  = SMB_DBG_CODE(11),   /* 0x030A002C */
355        SMB_DBG_PAGE_IN                   = SMB_DBG_CODE(12),   /* 0x030A0030 */
356        SMB_DBG_INACTIVE                  = SMB_DBG_CODE(13),   /* 0x030A0034 */
357        SMB_DBG_IOCTL                     = SMB_DBG_CODE(14),   /* 0x030A0038 */
358        SMB_DBG_LINK                      = SMB_DBG_CODE(15),   /* 0x030A003C */
359        SMB_DBG_LOOKUP                    = SMB_DBG_CODE(16),   /* 0x030A0040 */
360        SMB_DBG_MKDIR                     = SMB_DBG_CODE(17),   /* 0x030A0044 */
361        SMB_DBG_MKNODE                    = SMB_DBG_CODE(18),   /* 0x030A0048 */
362        SMB_DBG_MMAP                      = SMB_DBG_CODE(19),   /* 0x030A004C */
363        SMB_DBG_MNOMAP                    = SMB_DBG_CODE(20),   /* 0x030A0050 */
364        SMB_DBG_OPEN                      = SMB_DBG_CODE(21),   /* 0x030A0054 */
365        SMB_DBG_CMPD_OPEN                 = SMB_DBG_CODE(22),   /* 0x030A0058 */
366        SMB_DBG_PATHCONF                  = SMB_DBG_CODE(23),   /* 0x030A005C */
367        SMB_DBG_PAGE_OUT                  = SMB_DBG_CODE(24),   /* 0x030A0060 */
368        SMB_DBG_COPYFILE                  = SMB_DBG_CODE(25),   /* 0x030A0064 */
369        SMB_DBG_READ                      = SMB_DBG_CODE(26),   /* 0x030A0068 */
370        SMB_DBG_READ_DIR                  = SMB_DBG_CODE(27),   /* 0x030A006C */
371        SMB_DBG_READ_DIR_ATTR             = SMB_DBG_CODE(28),   /* 0x030A0070 */
372        SMB_DBG_READ_LINK                 = SMB_DBG_CODE(29),   /* 0x030A0074 */
373        SMB_DBG_RECLAIM                   = SMB_DBG_CODE(30),   /* 0x030A0078 */
374        SMB_DBG_REMOVE                    = SMB_DBG_CODE(31),   /* 0x030A007C */
375        SMB_DBG_RENAME                    = SMB_DBG_CODE(32),   /* 0x030A0080 */
376        SMB_DBG_RM_DIR                    = SMB_DBG_CODE(33),   /* 0x030A0084 */
377        SMB_DBG_SET_ATTR                  = SMB_DBG_CODE(34),   /* 0x030A0088 */
378        SMB_DBG_SYM_LINK                  = SMB_DBG_CODE(35),   /* 0x030A008C */
379        SMB_DBG_WRITE                     = SMB_DBG_CODE(36),   /* 0x030A0090 */
380        SMB_DBG_STRATEGY                  = SMB_DBG_CODE(37),   /* 0x030A0094 */
381        SMB_DBG_GET_XATTR                 = SMB_DBG_CODE(38),   /* 0x030A0098 */
382        SMB_DBG_SET_XATTR                 = SMB_DBG_CODE(39),   /* 0x030A009C */
383        SMB_DBG_RM_XATTR                  = SMB_DBG_CODE(40),   /* 0x030A00A0 */
384        SMB_DBG_LIST_XATTR                = SMB_DBG_CODE(41),   /* 0x030A00A4 */
385        SMB_DBG_MONITOR                   = SMB_DBG_CODE(42),   /* 0x030A00A8 */
386        SMB_DBG_GET_NSTREAM               = SMB_DBG_CODE(43),   /* 0x030A00AC */
387        SMB_DBG_MAKE_NSTREAM              = SMB_DBG_CODE(44),   /* 0x030A00B0 */
388        SMB_DBG_RM_NSTREAM                = SMB_DBG_CODE(45),   /* 0x030A00B4 */
389        SMB_DBG_ACCESS                    = SMB_DBG_CODE(46),   /* 0x030A00B8 */
390        SMB_DBG_ALLOCATE                  = SMB_DBG_CODE(47),   /* 0x030A00BC */
391
392        /* Sub Functions */
393        SMB_DBG_SMBFS_CLOSE               = SMB_DBG_CODE(48),   /* 0x030A00C0 */
394        SMB_DBG_SMBFS_CREATE              = SMB_DBG_CODE(49),   /* 0x030A00C4 */
395        SMB_DBG_SMBFS_FSYNC               = SMB_DBG_CODE(50),   /* 0x030A00C8 */
396        SMB_DBG_SMB_FSYNC                 = SMB_DBG_CODE(51),   /* 0x030A00CC */
397        SMB_DBG_SMBFS_UPDATE_CACHE        = SMB_DBG_CODE(52),   /* 0x030A00D0 */
398        SMB_DBG_SMBFS_OPEN                = SMB_DBG_CODE(53),   /* 0x030A00D4 */
399        SMB_DBG_SMB_READ                  = SMB_DBG_CODE(54),   /* 0x030A00D8 */
400        SMB_DBG_SMB_RW_ASYNC              = SMB_DBG_CODE(55),   /* 0x030A00DC */
401        SMB_DBG_SMB_RW_FILL               = SMB_DBG_CODE(56),   /* 0x030A00E0 */
402        SMB_DBG_PACK_ATTR_BLK             = SMB_DBG_CODE(57),   /* 0x030A00E4 */
403        SMB_DBG_SMBFS_REMOVE              = SMB_DBG_CODE(58),   /* 0x030A00E8 */
404        SMB_DBG_SMBFS_SETATTR             = SMB_DBG_CODE(59),   /* 0x030A00EC */
405        SMB_DBG_SMBFS_GET_SEC             = SMB_DBG_CODE(60),   /* 0x030A00F0 */
406        SMB_DBG_SMBFS_SET_SEC             = SMB_DBG_CODE(61),   /* 0x030A00F4 */
407        SMB_DBG_SMBFS_GET_MAX_ACCESS      = SMB_DBG_CODE(62),   /* 0x030A00F8 */
408        SMB_DBG_SMBFS_LOOKUP              = SMB_DBG_CODE(63),   /* 0x030A00FC */
409        SMB_DBG_SMBFS_NOTIFY              = SMB_DBG_CODE(64),   /* 0x030A0100 */
410
411        SMB_DBG_GET_ATTRLIST_BULK         = SMB_DBG_CODE(65),   /* 0x030A0104 */
412        SMB_DBG_UPDATE_CTX                = SMB_DBG_CODE(66),   /* 0x030A0108 */
413};
414
415
416#endif	/* KERNEL */
417
418#endif /* _SMBFS_SMBFS_H_ */
419