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