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 /*
22148c5f43SAlan Wright  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23a8e9db1cSGordon Ross  * Copyright 2020 Tintri by DDN, Inc. All rights reserved.
24*61b20185SGordon Ross  * Copyright 2022 RackTop Systems, Inc.
25da6c28aaSamw  */
27da6c28aaSamw /*
28da6c28aaSamw  * Structures and type definitions for the SMB module.
29da6c28aaSamw  */
31faa1795aSjb #ifndef _SMBSRV_SMB_KTYPES_H
32faa1795aSjb #define	_SMBSRV_SMB_KTYPES_H
34da6c28aaSamw #ifdef	__cplusplus
35da6c28aaSamw extern "C" {
36da6c28aaSamw #endif
38faa1795aSjb #include <sys/note.h>
39da6c28aaSamw #include <sys/systm.h>
40da6c28aaSamw #include <sys/param.h>
41da6c28aaSamw #include <sys/types.h>
42da6c28aaSamw #include <sys/synch.h>
43da6c28aaSamw #include <sys/taskq.h>
443db3f65cSamw #include <sys/socket.h>
45da6c28aaSamw #include <sys/acl.h>
46da6c28aaSamw #include <sys/sdt.h>
47c8ec8eeaSjose borrego #include <sys/stat.h>
48da6c28aaSamw #include <sys/vnode.h>
49da6c28aaSamw #include <sys/cred.h>
500f1702c5SYu Xiangning #include <netinet/in.h>
510f1702c5SYu Xiangning #include <sys/ksocket.h>
52faa1795aSjb #include <sys/fem.h>
53da6c28aaSamw #include <smbsrv/smb.h>
54a90cf9f2SGordon Ross #include <smbsrv/smb2.h>
55da6c28aaSamw #include <smbsrv/smbinfo.h>
56da6c28aaSamw #include <smbsrv/mbuf.h>
576537f381Sas #include <smbsrv/smb_sid.h>
583db3f65cSamw #include <smbsrv/smb_xdr.h>
5921b7895dSjb #include <smbsrv/netbios.h>
60da6c28aaSamw #include <smbsrv/smb_vops.h>
61148c5f43SAlan Wright #include <smbsrv/smb_kstat.h>
63b819cea2SGordon Ross struct __door_handle;	/* <sys/door.h> */
64b819cea2SGordon Ross struct edirent;		/* <sys/extdirent.h> */
658d94f651SGordon Ross struct nvlist;
66b819cea2SGordon Ross 
672c2961f8Sjose borrego struct smb_disp_entry;
68faa1795aSjb struct smb_request;
69faa1795aSjb struct smb_server;
709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct smb_event;
718622ec45SGordon Ross struct smb_export;
73148c5f43SAlan Wright /*
74148c5f43SAlan Wright  * Accumulated time and queue length statistics.
75148c5f43SAlan Wright  *
76148c5f43SAlan Wright  * Accumulated time statistics are kept as a running sum of "active" time.
77148c5f43SAlan Wright  * Queue length statistics are kept as a running sum of the product of queue
78148c5f43SAlan Wright  * length and elapsed time at that length -- i.e., a Riemann sum for queue
79148c5f43SAlan Wright  * length integrated against time.  (You can also think of the active time as a
80148c5f43SAlan Wright  * Riemann sum, for the boolean function (queue_length > 0) integrated against
81148c5f43SAlan Wright  * time, or you can think of it as the Lebesgue measure of the set on which
82148c5f43SAlan Wright  * queue_length > 0.)
83148c5f43SAlan Wright  *
84148c5f43SAlan Wright  *		^
85148c5f43SAlan Wright  *		|			_________
86148c5f43SAlan Wright  *		8			| i4	|
87148c5f43SAlan Wright  *		|			|	|
88148c5f43SAlan Wright  *	Queue	6			|	|
89148c5f43SAlan Wright  *	Length	|	_________	|	|
90148c5f43SAlan Wright  *		4	| i2	|_______|	|
91148c5f43SAlan Wright  *		|	|	    i3		|
92148c5f43SAlan Wright  *		2_______|			|
93148c5f43SAlan Wright  *		|    i1				|
94148c5f43SAlan Wright  *		|_______________________________|
95148c5f43SAlan Wright  *		Time->	t1	t2	t3	t4
96148c5f43SAlan Wright  *
97148c5f43SAlan Wright  * At each change of state (entry or exit from the queue), we add the elapsed
98148c5f43SAlan Wright  * time (since the previous state change) to the active time if the queue length
99148c5f43SAlan Wright  * was non-zero during that interval; and we add the product of the elapsed time
100148c5f43SAlan Wright  * times the queue length to the running length*time sum.
101148c5f43SAlan Wright  *
102148c5f43SAlan Wright  * This method is generalizable to measuring residency in any defined system:
103148c5f43SAlan Wright  * instead of queue lengths, think of "outstanding RPC calls to server X".
104148c5f43SAlan Wright  *
105148c5f43SAlan Wright  * A large number of I/O subsystems have at least two basic "lists" of
106148c5f43SAlan Wright  * transactions they manage: one for transactions that have been accepted for
107148c5f43SAlan Wright  * processing but for which processing has yet to begin, and one for
108148c5f43SAlan Wright  * transactions which are actively being processed (but not done). For this
109148c5f43SAlan Wright  * reason, two cumulative time statistics are defined here: wait (pre-service)
110148c5f43SAlan Wright  * time, and run (service) time.
111148c5f43SAlan Wright  *
112148c5f43SAlan Wright  * All times are 64-bit nanoseconds (hrtime_t), as returned by gethrtime().
113148c5f43SAlan Wright  *
114148c5f43SAlan Wright  * The units of cumulative busy time are accumulated nanoseconds. The units of
115148c5f43SAlan Wright  * cumulative length*time products are elapsed time times queue length.
116148c5f43SAlan Wright  *
117148c5f43SAlan Wright  * Updates to the fields below are performed implicitly by calls to
118148c5f43SAlan Wright  * these functions:
119148c5f43SAlan Wright  *
120148c5f43SAlan Wright  *	smb_srqueue_init()
121148c5f43SAlan Wright  *	smb_srqueue_destroy()
122148c5f43SAlan Wright  *	smb_srqueue_waitq_enter()
123148c5f43SAlan Wright  *	smb_srqueue_runq_exit()
124148c5f43SAlan Wright  *	smb_srqueue_waitq_to_runq()
125148c5f43SAlan Wright  *	smb_srqueue_update()
126148c5f43SAlan Wright  *
127148c5f43SAlan Wright  * These fields should never be updated by any other means.
128148c5f43SAlan Wright  */
129148c5f43SAlan Wright typedef struct smb_srqueue {
130148c5f43SAlan Wright 	kmutex_t	srq_mutex;
131148c5f43SAlan Wright 	hrtime_t	srq_wlastupdate;
132148c5f43SAlan Wright 	hrtime_t	srq_wtime;
133148c5f43SAlan Wright 	hrtime_t	srq_wlentime;
134148c5f43SAlan Wright 	hrtime_t	srq_rlastupdate;
135148c5f43SAlan Wright 	hrtime_t	srq_rtime;
136148c5f43SAlan Wright 	hrtime_t	srq_rlentime;
137148c5f43SAlan Wright 	uint32_t	srq_wcnt;
138148c5f43SAlan Wright 	uint32_t	srq_rcnt;
139148c5f43SAlan Wright } smb_srqueue_t;
140148c5f43SAlan Wright 
141148c5f43SAlan Wright /*
142148c5f43SAlan Wright  * The fields with the prefix 'ly_a' contain the statistics collected since the
143148c5f43SAlan Wright  * server was last started ('a' for 'aggregated'). The fields with the prefix
144148c5f43SAlan Wright  * 'ly_d' contain the statistics collected since the last snapshot ('d' for
145148c5f43SAlan Wright  * 'delta').
146148c5f43SAlan Wright  */
147148c5f43SAlan Wright typedef struct smb_latency {
148148c5f43SAlan Wright 	kmutex_t	ly_mutex;
149148c5f43SAlan Wright 	uint64_t	ly_a_nreq;
150148c5f43SAlan Wright 	hrtime_t	ly_a_sum;
151148c5f43SAlan Wright 	hrtime_t	ly_a_mean;
152148c5f43SAlan Wright 	hrtime_t	ly_a_stddev;
153148c5f43SAlan Wright 	uint64_t	ly_d_nreq;
154148c5f43SAlan Wright 	hrtime_t	ly_d_sum;
155148c5f43SAlan Wright 	hrtime_t	ly_d_mean;
156148c5f43SAlan Wright 	hrtime_t	ly_d_stddev;
157148c5f43SAlan Wright } smb_latency_t;
158148c5f43SAlan Wright 
1598622ec45SGordon Ross typedef struct smb_disp_stats {
1608622ec45SGordon Ross 	volatile uint64_t sdt_txb;
1618622ec45SGordon Ross 	volatile uint64_t sdt_rxb;
1628622ec45SGordon Ross 	smb_latency_t	sdt_lat;
1638622ec45SGordon Ross } smb_disp_stats_t;
1648622ec45SGordon Ross 
165da6c28aaSamw int smb_noop(void *, size_t, int);
167da6c28aaSamw #define	SMB_AUDIT_STACK_DEPTH	16
168da6c28aaSamw #define	SMB_AUDIT_BUF_MAX_REC	16
169da6c28aaSamw #define	SMB_AUDIT_NODE		0x00000001
171c8ec8eeaSjose borrego /*
172c8ec8eeaSjose borrego  * Maximum number of records returned in SMBsearch, SMBfind
173c8ec8eeaSjose borrego  * and SMBfindunique response. Value set to 10 for compatibility
174c8ec8eeaSjose borrego  * with Windows.
175c8ec8eeaSjose borrego  */
176c8ec8eeaSjose borrego #define	SMB_MAX_SEARCH		10
177c8ec8eeaSjose borrego 
1787f667e74Sjose borrego #define	SMB_SEARCH_ATTRIBUTES    \
1797f667e74Sjose borrego 	(FILE_ATTRIBUTE_HIDDEN | \
1807f667e74Sjose borrego 	FILE_ATTRIBUTE_SYSTEM |  \
1817f667e74Sjose borrego 	FILE_ATTRIBUTE_DIRECTORY)
1827f667e74Sjose borrego 
1832c1b14e5Sjose borrego #define	SMB_SEARCH_HIDDEN(sattr) ((sattr) & FILE_ATTRIBUTE_HIDDEN)
1842c1b14e5Sjose borrego #define	SMB_SEARCH_SYSTEM(sattr) ((sattr) & FILE_ATTRIBUTE_SYSTEM)
1852c1b14e5Sjose borrego #define	SMB_SEARCH_DIRECTORY(sattr) ((sattr) & FILE_ATTRIBUTE_DIRECTORY)
1867f667e74Sjose borrego #define	SMB_SEARCH_ALL(sattr) ((sattr) & SMB_SEARCH_ATTRIBUTES)
1872c1b14e5Sjose borrego 
188da6c28aaSamw typedef struct {
189da6c28aaSamw 	uint32_t		anr_refcnt;
190da6c28aaSamw 	int			anr_depth;
191da6c28aaSamw 	pc_t			anr_stack[SMB_AUDIT_STACK_DEPTH];
192da6c28aaSamw } smb_audit_record_node_t;
194da6c28aaSamw typedef struct {
195da6c28aaSamw 	int			anb_index;
196da6c28aaSamw 	int			anb_max_index;
197da6c28aaSamw 	smb_audit_record_node_t	anb_records[SMB_AUDIT_BUF_MAX_REC];
198da6c28aaSamw } smb_audit_buf_node_t;
200da6c28aaSamw /*
201da6c28aaSamw  * Thread State Machine
202da6c28aaSamw  * --------------------
203da6c28aaSamw  *
204da6c28aaSamw  *			    T5			   T0
205da6c28aaSamw  * smb_thread_destroy()	<-------+		+------- smb_thread_init()
206da6c28aaSamw  *                              |		|
207da6c28aaSamw  *				|		v
208da6c28aaSamw  *			+-----------------------------+
209da6c28aaSamw  *			|   SMB_THREAD_STATE_EXITED   |<---+
210da6c28aaSamw  *			+-----------------------------+	   |
211da6c28aaSamw  *				      | T1		   |
212da6c28aaSamw  *				      v			   |
213da6c28aaSamw  *			+-----------------------------+	   |
214da6c28aaSamw  *			|  SMB_THREAD_STATE_STARTING  |	   |
215da6c28aaSamw  *			+-----------------------------+	   |
216da6c28aaSamw  *				     | T2		   | T4
217da6c28aaSamw  *				     v			   |
218da6c28aaSamw  *			+-----------------------------+	   |
219da6c28aaSamw  *			|  SMB_THREAD_STATE_RUNNING   |	   |
220da6c28aaSamw  *			+-----------------------------+	   |
221da6c28aaSamw  *				     | T3		   |
222da6c28aaSamw  *				     v			   |
223da6c28aaSamw  *			+-----------------------------+	   |
224da6c28aaSamw  *			|  SMB_THREAD_STATE_EXITING   |----+
225da6c28aaSamw  *			+-----------------------------+
226da6c28aaSamw  *
227da6c28aaSamw  * Transition T0
228da6c28aaSamw  *
229da6c28aaSamw  *    This transition is executed in smb_thread_init().
230da6c28aaSamw  *
231da6c28aaSamw  * Transition T1
232da6c28aaSamw  *
233da6c28aaSamw  *    This transition is executed in smb_thread_start().
234da6c28aaSamw  *
235da6c28aaSamw  * Transition T2
236da6c28aaSamw  *
237da6c28aaSamw  *    This transition is executed by the thread itself when it starts running.
238da6c28aaSamw  *
239da6c28aaSamw  * Transition T3
240da6c28aaSamw  *
241da6c28aaSamw  *    This transition is executed by the thread itself in
242da6c28aaSamw  *    smb_thread_entry_point() just before calling thread_exit().
243da6c28aaSamw  *
244da6c28aaSamw  *
245da6c28aaSamw  * Transition T4
246da6c28aaSamw  *
247da6c28aaSamw  *    This transition is executed in smb_thread_stop().
248da6c28aaSamw  *
249da6c28aaSamw  * Transition T5
250da6c28aaSamw  *
251da6c28aaSamw  *    This transition is executed in smb_thread_destroy().
252da6c28aaSamw  */
253da6c28aaSamw typedef enum smb_thread_state {
254da6c28aaSamw 	SMB_THREAD_STATE_STARTING = 0,
257b819cea2SGordon Ross 	SMB_THREAD_STATE_EXITED,
258b819cea2SGordon Ross 	SMB_THREAD_STATE_FAILED
259da6c28aaSamw } smb_thread_state_t;
261da6c28aaSamw struct _smb_thread;
263da6c28aaSamw typedef void (*smb_thread_ep_t)(struct _smb_thread *, void *ep_arg);
265da6c28aaSamw #define	SMB_THREAD_MAGIC	0x534D4254	/* SMBT */
267da6c28aaSamw typedef struct _smb_thread {
268da6c28aaSamw 	uint32_t		sth_magic;
269a90cf9f2SGordon Ross 	char			sth_name[32];
270da6c28aaSamw 	smb_thread_state_t	sth_state;
271da6c28aaSamw 	kthread_t		*sth_th;
272da6c28aaSamw 	kt_did_t		sth_did;
273da6c28aaSamw 	smb_thread_ep_t		sth_ep;
274da6c28aaSamw 	void			*sth_ep_arg;
27508344b29SGordon Ross 	pri_t			sth_pri;
276da6c28aaSamw 	boolean_t		sth_kill;
277da6c28aaSamw 	kmutex_t		sth_mtx;
278da6c28aaSamw 	kcondvar_t		sth_cv;
279da6c28aaSamw } smb_thread_t;
281da6c28aaSamw /*
282da6c28aaSamw  * Pool of IDs
283da6c28aaSamw  * -----------
284da6c28aaSamw  *
285da6c28aaSamw  *    A pool of IDs is a pool of 16 bit numbers. It is implemented as a bitmap.
286da6c28aaSamw  *    A bit set to '1' indicates that that particular value has been allocated.
287da6c28aaSamw  *    The allocation process is done shifting a bit through the whole bitmap.
288da6c28aaSamw  *    The current position of that index bit is kept in the smb_idpool_t
289da6c28aaSamw  *    structure and represented by a byte index (0 to buffer size minus 1) and
290da6c28aaSamw  *    a bit index (0 to 7).
291da6c28aaSamw  *
292da6c28aaSamw  *    The pools start with a size of 8 bytes or 64 IDs. Each time the pool runs
293da6c28aaSamw  *    out of IDs its current size is doubled until it reaches its maximum size
294da6c28aaSamw  *    (8192 bytes or 65536 IDs). The IDs 0 and 65535 are never given out which
295da6c28aaSamw  *    means that a pool can have a maximum number of 65534 IDs available.
296da6c28aaSamw  */
297da6c28aaSamw #define	SMB_IDPOOL_MAGIC	0x4944504C	/* IDPL */
298da6c28aaSamw #define	SMB_IDPOOL_MIN_SIZE	64	/* Number of IDs to begin with */
299da6c28aaSamw #define	SMB_IDPOOL_MAX_SIZE	64 * 1024
301da6c28aaSamw typedef struct smb_idpool {
302da6c28aaSamw 	uint32_t	id_magic;
303da6c28aaSamw 	kmutex_t	id_mutex;
304da6c28aaSamw 	uint8_t		*id_pool;
305da6c28aaSamw 	uint32_t	id_size;
30612b65585SGordon Ross 	uint32_t	id_maxsize;
307da6c28aaSamw 	uint8_t		id_bit;
308da6c28aaSamw 	uint8_t		id_bit_idx;
309da6c28aaSamw 	uint32_t	id_idx;
310da6c28aaSamw 	uint32_t	id_idx_msk;
311da6c28aaSamw 	uint32_t	id_free_counter;
312da6c28aaSamw 	uint32_t	id_max_free_counter;
313da6c28aaSamw } smb_idpool_t;
315da6c28aaSamw /*
3162c2961f8Sjose borrego  * Maximum size of a Transport Data Unit when CAP_LARGE_READX and
3172c2961f8Sjose borrego  * CAP_LARGE_WRITEX are not set.  CAP_LARGE_READX/CAP_LARGE_WRITEX
3182c2961f8Sjose borrego  * allow the payload to exceed the negotiated buffer size.
31921b7895dSjb  *     4 --> NBT/TCP Transport Header.
32021b7895dSjb  *    32 --> SMB Header
32121b7895dSjb  *     1 --> Word Count byte
32221b7895dSjb  *   510 --> Maximum Number of bytes of the Word Table (2 * 255)
32321b7895dSjb  *     2 --> Byte count of the data
32421b7895dSjb  * 65535 --> Maximum size of the data
32521b7895dSjb  * -----
32621b7895dSjb  * 66084
327da6c28aaSamw  */
3282c2961f8Sjose borrego #define	SMB_REQ_MAX_SIZE	66560		/* 65KB */
33121b7895dSjb #define	SMB_TXREQ_MAGIC		0X54524251	/* 'TREQ' */
3325cdbe942Sjb typedef struct {
33321b7895dSjb 	list_node_t	tr_lnd;
334a90cf9f2SGordon Ross 	uint32_t	tr_magic;
33521b7895dSjb 	int		tr_len;
33621b7895dSjb 	uint8_t		tr_buf[SMB_XPRT_MAX_SIZE];
33721b7895dSjb } smb_txreq_t;
3395cdbe942Sjb #define	SMB_TXLST_MAGIC		0X544C5354	/* 'TLST' */
3405cdbe942Sjb typedef struct {
3415cdbe942Sjb 	uint32_t	tl_magic;
3425cdbe942Sjb 	kmutex_t	tl_mutex;
343a90cf9f2SGordon Ross 	kcondvar_t	tl_wait_cv;
3445cdbe942Sjb 	boolean_t	tl_active;
3455cdbe942Sjb } smb_txlst_t;
347da6c28aaSamw /*
348faa1795aSjb  * Maximum buffer size for NT is 37KB.  If all clients are Windows 2000, this
349faa1795aSjb  * can be changed to 64KB.  37KB must be used with a mix of NT/Windows 2000
350faa1795aSjb  * clients because NT loses directory entries when values greater than 37KB are
351faa1795aSjb  * used.
352faa1795aSjb  *
353faa1795aSjb  * Note: NBT_MAXBUF will be subtracted from the specified max buffer size to
354faa1795aSjb  * account for the NBT header.
355da6c28aaSamw  */
356faa1795aSjb #define	NBT_MAXBUF		8
357faa1795aSjb #define	SMB_NT_MAXBUF		(37 * 1024)
359da6c28aaSamw #define	OUTBUFSIZE		(65 * 1024)
360da6c28aaSamw #define	SMBHEADERSIZE		32
361da6c28aaSamw #define	SMBND_HASH_MASK		(0xFF)
362da6c28aaSamw #define	MAX_IOVEC		512
363da6c28aaSamw #define	MAX_READREF		(8 * 1024)
365da6c28aaSamw #define	SMB_WORKER_MIN		4
366da6c28aaSamw #define	SMB_WORKER_DEFAULT	64
367da6c28aaSamw #define	SMB_WORKER_MAX		1024
369da6c28aaSamw /*
3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Destructor object used in the locked-list delete queue.
371da6c28aaSamw  */
3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_DTOR_MAGIC		0x44544F52	/* DTOR */
3739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_DTOR_VALID(d)	\
3749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     ASSERT(((d) != NULL) && ((d)->dt_magic == SMB_DTOR_MAGIC))
3769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States typedef void (*smb_dtorproc_t)(void *);
3789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States typedef struct smb_dtor {
3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_node_t	dt_lnd;
380a90cf9f2SGordon Ross 	uint32_t	dt_magic;
3819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	void		*dt_object;
3829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_dtorproc_t	dt_proc;
3839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } smb_dtor_t;
385da6c28aaSamw typedef struct smb_llist {
386da6c28aaSamw 	krwlock_t	ll_lock;
387da6c28aaSamw 	list_t		ll_list;
388da6c28aaSamw 	uint32_t	ll_count;
389da6c28aaSamw 	uint64_t	ll_wrop;