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. 234e065a9fSAlexander Stetsenko * Copyright 2020 RackTop Systems, Inc. 24a8e9db1cSGordon Ross * Copyright 2020 Tintri by DDN, Inc. All rights reserved. 25da6c28aaSamw */ 26da6c28aaSamw 27da6c28aaSamw /* 28da6c28aaSamw * Structures and type definitions for the SMB module. 29da6c28aaSamw */ 30da6c28aaSamw 31faa1795aSjb #ifndef _SMBSRV_SMB_KTYPES_H 32faa1795aSjb #define _SMBSRV_SMB_KTYPES_H 33da6c28aaSamw 34da6c28aaSamw #ifdef __cplusplus 35da6c28aaSamw extern "C" { 36da6c28aaSamw #endif 37da6c28aaSamw 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> 62da6c28aaSamw 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; 72da6c28aaSamw 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); 166da6c28aaSamw 167da6c28aaSamw #define SMB_AUDIT_STACK_DEPTH 16 168da6c28aaSamw #define SMB_AUDIT_BUF_MAX_REC 16 169da6c28aaSamw #define SMB_AUDIT_NODE 0x00000001 170da6c28aaSamw 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; 193da6c28aaSamw 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; 199da6c28aaSamw 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, 255da6c28aaSamw SMB_THREAD_STATE_RUNNING, 256da6c28aaSamw SMB_THREAD_STATE_EXITING, 257b819cea2SGordon Ross SMB_THREAD_STATE_EXITED, 258b819cea2SGordon Ross SMB_THREAD_STATE_FAILED 259da6c28aaSamw } smb_thread_state_t; 260da6c28aaSamw 261da6c28aaSamw struct _smb_thread; 262da6c28aaSamw 263da6c28aaSamw typedef void (*smb_thread_ep_t)(struct _smb_thread *, void *ep_arg); 264da6c28aaSamw 265da6c28aaSamw #define SMB_THREAD_MAGIC 0x534D4254 /* SMBT */ 266da6c28aaSamw 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; 280da6c28aaSamw 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 300da6c28aaSamw 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; 314da6c28aaSamw 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 */ 32921b7895dSjb #define SMB_XPRT_MAX_SIZE (SMB_REQ_MAX_SIZE + NETBIOS_HDR_SZ) 330da6c28aaSamw 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; 3385cdbe942Sjb 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; 3465cdbe942Sjb 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) 358da6c28aaSamw 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) 364da6c28aaSamw 365da6c28aaSamw #define SMB_WORKER_MIN 4 366da6c28aaSamw #define SMB_WORKER_DEFAULT 64 367da6c28aaSamw #define SMB_WORKER_MAX 1024 368da6c28aaSamw 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)) 375da6c28aaSamw 3769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States typedef void (*smb_dtorproc_t)(void *); 377da6c28aaSamw 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; 384da6c28aaSamw 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; 3909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States kmutex_t ll_mutex; 3919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States list_t ll_deleteq; 392