1 /* 2 * Copyright (c) 2000-2001 Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Boris Popov. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: smb_conn.h,v 1.32.42.1 2005/05/27 02:35:29 lindak Exp $ 33 */ 34 35 /* 36 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 37 * Use is subject to license terms. 38 * 39 * Portions Copyright (C) 2001 - 2013 Apple Inc. All rights reserved. 40 * Copyright 2018 Nexenta Systems, Inc. All rights reserved. 41 * Copyright 2024 RackTop Systems, Inc. 42 */ 43 44 #ifndef _SMB_CONN_H 45 #define _SMB_CONN_H 46 47 #include <sys/dditypes.h> 48 #include <sys/t_lock.h> 49 #include <sys/queue.h> /* for SLIST below */ 50 #include <sys/uio.h> 51 #include <netsmb/smb_dev.h> 52 #include <netsmb/nsmb_kcrypt.h> 53 54 /* 55 * Credentials of user/process for processing in the connection procedures 56 */ 57 typedef struct smb_cred { 58 struct cred *scr_cred; 59 } smb_cred_t; 60 61 /* 62 * Common object flags 63 */ 64 #define SMBO_GONE 0x1000000 65 66 /* 67 * Bits in vc_flags (a.k.a. vc_co.co_flags) 68 * Note: SMBO_GONE is also in vc_flags 69 */ 70 #define SMBV_UNICODE 0x0040 /* conn configured to use Unicode */ 71 #define SMBV_EXT_SEC 0x0080 /* conn to use extended security */ 72 #define SMBV_SIGNING 0x0100 /* negotiated signing */ 73 #define SMBV_SMB2 0x0200 /* VC using SMB 2 or 3 */ 74 #define SMBV_HAS_FILEIDS 0x0400 /* Use File IDs for hash and inums */ 75 #define SMBV_NO_WRITE_THRU 0x0800 /* Can't use ... */ 76 77 /* 78 * Note: the common "obj" level uses this GONE flag by 79 * the name SMBO_GONE. Keep this alias as a reminder. 80 */ 81 #define SMBV_GONE SMBO_GONE 82 83 /* 84 * bits in smb_share ss_flags (a.k.a. ss_co.co_flags) 85 */ 86 #define SMBS_RECONNECTING 0x0002 87 #define SMBS_CONNECTED 0x0004 88 #define SMBS_TCON_WAIT 0x0008 89 #define SMBS_FST_FAT 0x0010 /* share FS Type is FAT */ 90 /* 91 * Note: the common "obj" level uses this GONE flag by 92 * the name SMBO_GONE. Keep this alias as a reminder. 93 */ 94 #define SMBS_GONE SMBO_GONE 95 96 /* 97 * bits in smb_fh fh_flags (a.k.a. ss_co.co_flags) 98 */ 99 #define SMBFH_VALID 0x0002 /* FID is valid */ 100 /* 101 * Note: the common "obj" level uses this GONE flag by 102 * the name SMBO_GONE. Keep this alias as a reminder. 103 */ 104 #define SMBFH_GONE SMBO_GONE 105 106 struct smb_rq; 107 /* This declares struct smb_rqhead */ 108 TAILQ_HEAD(smb_rqhead, smb_rq); 109 110 #define SMB_NBTIMO 15 111 #define SMB_DEFRQTIMO 30 /* 30 for oplock revoke/writeback */ 112 #define SMBWRTTIMO 60 113 #define SMBSSNSETUPTIMO 60 114 #define SMBNOREPLYWAIT (0) 115 116 #define SMB_DIALECT(vcp) ((vcp)->vc_sopt.sv_proto) 117 118 /* 119 * Connection object 120 */ 121 122 #define SMB_CO_LOCK(cp) mutex_enter(&(cp)->co_lock) 123 #define SMB_CO_UNLOCK(cp) mutex_exit(&(cp)->co_lock) 124 125 /* 126 * Common part of smb_vc, smb_share 127 * Locking: co_lock protects most 128 * fields in this struct, except 129 * as noted below: 130 */ 131 struct smb_connobj { 132 kmutex_t co_lock; 133 int co_level; /* SMBL_ */ 134 int co_flags; 135 int co_usecount; 136 137 /* Note: must lock co_parent before child. */ 138 struct smb_connobj *co_parent; 139 140 /* this.co_lock protects the co_children list */ 141 SLIST_HEAD(, smb_connobj) co_children; 142 143 /* 144 * Linkage in parent's list of children. 145 * Must hold parent.co_lock to traverse. 146 */ 147 SLIST_ENTRY(smb_connobj) co_next; 148 149 /* These two are set only at creation. */ 150 void (*co_gone)(struct smb_connobj *); 151 void (*co_free)(struct smb_connobj *); 152 }; 153 typedef struct smb_connobj smb_connobj_t; 154 155 /* 156 * "Level" in the connection object hierarchy 157 */ 158 enum smbco_level { 159 SMBL_SM = 0, 160 SMBL_VC = 1, 161 SMBL_SHARE = 2, 162 SMBL_FH = 3 163 }; 164 165 /* 166 * SMB1 Negotiated protocol parameters 167 * Note: All set to zero at start of nsmb_iod_negotiate 168 */ 169 struct smb_sopt { 170 uint16_t sv_proto; /* protocol dialect */ 171 uchar_t sv_sm; /* security mode */ 172 int16_t sv_tz; /* offset in min relative to UTC */ 173 uint16_t sv_maxmux; /* max number of outstanding rq's */ 174 uint16_t sv_maxvcs; /* max number of VCs */ 175 uint16_t sv_rawmode; 176 uint32_t sv_maxtx; /* maximum transmit buf size */ 177 uint32_t sv_maxraw; /* maximum raw-buffer size */ 178 uint32_t sv_skey; /* session key */ 179 uint32_t sv_caps; /* capabilites SMB_CAP_ */ 180 181 /* SMB2+ fields */ 182 uint32_t sv2_capabilities; /* capabilities */ 183 uint32_t sv2_maxtransact; /* max transact size */ 184 uint32_t sv2_maxread; /* max read size */ 185 uint32_t sv2_maxwrite; /* max write size */ 186 uint16_t sv2_security_mode; /* security mode */ 187 uint16_t sv2_sessflags; /* final session setup reply flags */ 188 uint8_t sv2_guid[16]; /* GUID */ 189 }; 190 typedef struct smb_sopt smb_sopt_t; 191 192 /* 193 * SMB1 I/O Deamon state 194 */ 195 struct smb_iods { 196 uint8_t is_hflags; /* SMB header flags */ 197 uint16_t is_hflags2; /* SMB header flags2 */ 198 uint16_t is_smbuid; /* SMB header UID */ 199 uint16_t is_next_mid; /* SMB header MID */ 200 uint32_t is_txmax; /* max tx/rx packet size */ 201 uint32_t is_rwmax; /* max read/write data size */ 202 uint32_t is_rxmax; /* max readx data size */ 203 uint32_t is_wxmax; /* max writex data size */ 204 /* Signing state */ 205 uint32_t is_next_seq; /* my next sequence number */ 206 207 }; 208 typedef struct smb_iods smb_iods_t; 209 210 /* 211 * Virtual Circuit to a server (really connection + session). 212 * Yes, calling this a "Virtual Circuit" is confusining, 213 * because it has nothing to do with the SMB notion of a 214 * "Virtual Circuit". 215 */ 216 typedef struct smb_vc { 217 struct smb_connobj vc_co; /* keep first! See CPTOVC */ 218 enum smbiod_state vc_state; 219 kcondvar_t vc_statechg; 220 221 zoneid_t vc_zoneid; 222 uid_t vc_owner; /* Unix owner */ 223 int vc_genid; /* "generation" ID */ 224 225 int vc_mackeylen; /* MAC key length */ 226 int vc_ssnkeylen; /* session key length */ 227 uint8_t *vc_mackey; /* MAC key buffer */ 228 uint8_t *vc_ssnkey; /* session key buffer */ 229 smb_crypto_mech_t vc_signmech; 230 struct smb_mac_ops *vc_sign_ops; 231 232 struct smb_tran_desc *vc_tdesc; /* transport ops. vector */ 233 void *vc_tdata; /* transport control block */ 234 235 /* SMB2+ fields */ 236 uint64_t vc2_oldest_message_id; 237 uint64_t vc2_next_message_id; 238 uint64_t vc2_limit_message_id; 239 uint64_t vc2_session_id; /* session id */ 240 uint64_t vc2_prev_session_id; /* for reconnect */ 241 uint32_t vc2_lease_key; /* lease key gen */ 242 243 /* SMB3+ fields */ 244 smb_crypto_mech_t vc3_preauthmech; 245 smb_crypto_mech_t vc3_crypt_mech; 246 247 uint16_t vc3_enc_cipherid; 248 uint16_t vc3_preauth_hashid; 249 uint8_t vc3_preauth_hashval[SHA512_DIGEST_LENGTH]; 250 uint_t vc3_preauth_hashfails; 251 252 /* Encrypt/decrypt keys can be 128 bit or 256 bit */ 253 uint8_t vc3_encrypt_key[AES256_KEY_LENGTH]; 254 uint32_t vc3_encrypt_key_len; 255 256 uint8_t vc3_decrypt_key[AES256_KEY_LENGTH]; 257 uint32_t vc3_decrypt_key_len; 258 259 /* SMB 3 Nonce used for encryption */ 260 uint64_t vc3_nonce_high; 261 uint64_t vc3_nonce_low; 262 263 kcondvar_t iod_idle; /* IOD thread idle CV */ 264 krwlock_t iod_rqlock; /* iod_rqlist */ 265 struct smb_rqhead iod_rqlist; /* list of active reqs */ 266 struct _kthread *iod_thr; /* the IOD (reader) thread */ 267 int iod_flags; /* see SMBIOD_* below */ 268 uint_t iod_muxcnt; /* num. active requests */ 269 uint_t iod_muxwant; /* waiting to be active */ 270 kcondvar_t iod_muxwait; 271 boolean_t iod_noresp; /* Logged "not responding" */ 272 273 smb_iods_t vc_iods; 274 smb_sopt_t vc_sopt; 275 276 /* This is copied in/out when IOD enters/returns */ 277 smbioc_ssn_work_t vc_work; 278 279 /* session identity, etc. */ 280 smbioc_ossn_t vc_ssn; 281 } smb_vc_t; 282 283 #define vc_lock vc_co.co_lock 284 #define vc_flags vc_co.co_flags 285 286 /* defines for members in vc_ssn */ 287 #define vc_owner vc_ssn.ssn_owner 288 #define vc_vopt vc_ssn.ssn_vopt 289 #define vc_minver vc_ssn.ssn_minver 290 #define vc_maxver vc_ssn.ssn_maxver 291 #define vc_srvname vc_ssn.ssn_srvname 292 #define vc_srvaddr vc_ssn.ssn_id.id_srvaddr 293 #define vc_domain vc_ssn.ssn_id.id_domain 294 #define vc_username vc_ssn.ssn_id.id_user 295 296 /* defines for members in vc_work */ 297 #define vc_cl_guid vc_work.wk_cl_guid 298 299 /* defines for members in vc_sopt ? */ 300 #define vc_maxmux vc_sopt.sv_maxmux 301 302 /* defines for members in vc_iods */ 303 #define vc_hflags vc_iods.is_hflags 304 #define vc_hflags2 vc_iods.is_hflags2 305 #define vc_smbuid vc_iods.is_smbuid 306 #define vc_next_mid vc_iods.is_next_mid 307 #define vc_txmax vc_iods.is_txmax 308 #define vc_rwmax vc_iods.is_rwmax 309 #define vc_rxmax vc_iods.is_rxmax 310 #define vc_wxmax vc_iods.is_wxmax 311 #define vc_next_seq vc_iods.is_next_seq 312 313 #define SMB_VC_LOCK(vcp) mutex_enter(&(vcp)->vc_lock) 314 #define SMB_VC_UNLOCK(vcp) mutex_exit(&(vcp)->vc_lock) 315 316 #define CPTOVC(cp) ((struct smb_vc *)((void *)(cp))) 317 #define VCTOCP(vcp) (&(vcp)->vc_co) 318 319 #define SMB_UNICODE_STRINGS(vcp) \ 320 (((vcp)->vc_flags & SMBV_SMB2) != 0 || \ 321 ((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE) != 0) 322 323 /* Bits in iod_flags */ 324 #define SMBIOD_RUNNING 0x0001 325 #define SMBIOD_SHUTDOWN 0x0002 326 327 /* 328 * smb_share structure describes connection to the given SMB share (tree). 329 * Connection to share is always built on top of the VC. 330 */ 331 332 typedef struct smb_share { 333 struct smb_connobj ss_co; /* keep first! See CPTOSS */ 334 kcondvar_t ss_conn_done; /* wait for reconnect */ 335 int ss_conn_waiters; 336 int ss_vcgenid; /* check VC generation ID */ 337 uint16_t ss_tid; /* TID */ 338 uint16_t ss_options; /* option support bits */ 339 uint32_t ss2_tree_id; 340 uint32_t ss2_share_flags; 341 uint32_t ss2_share_caps; 342 smbioc_oshare_t ss_ioc; 343 } smb_share_t; 344 345 #define ss_lock ss_co.co_lock 346 #define ss_flags ss_co.co_flags 347 348 #define ss_use ss_ioc.sh_use 349 #define ss_type ss_ioc.sh_type 350 #define ss_name ss_ioc.sh_name 351 #define ss_pass ss_ioc.sh_pass 352 353 #define SMB_SS_LOCK(ssp) mutex_enter(&(ssp)->ss_lock) 354 #define SMB_SS_UNLOCK(ssp) mutex_exit(&(ssp)->ss_lock) 355 356 #define CPTOSS(cp) ((struct smb_share *)((void *)(cp))) 357 #define SSTOCP(ssp) (&(ssp)->ss_co) 358 #define SSTOVC(ssp) CPTOVC(((ssp)->ss_co.co_parent)) 359 360 typedef struct smb2fid { 361 uint64_t fid_persistent; 362 uint64_t fid_volatile; 363 } smb2fid_t; 364 365 /* 366 * smb_fh struct describes an open file handle under some share. 367 */ 368 typedef struct smb_fh { 369 struct smb_connobj fh_co; /* keep first! See CPTOSS */ 370 int fh_vcgenid; /* check VC generation ID */ 371 uint32_t fh_rights; /* granted access */ 372 smb2fid_t fh_fid2; 373 uint16_t fh_fid1; 374 } smb_fh_t; 375 376 #define fh_lock fh_co.co_lock 377 #define fh_flags fh_co.co_flags 378 379 #define SMB_FH_LOCK(fhp) mutex_enter(&(fhp)->fh_lock) 380 #define SMB_FH_UNLOCK(fhp) mutex_exit(&(fhp)->fh_lock) 381 382 #define CPTOFH(cp) ((struct smb_fh *)((void *)(cp))) 383 #define FHTOCP(fhp) (&(fhp)->fh_co) 384 #define FHTOSS(fhp) CPTOSS(((fhp)->fh_co.co_parent)) 385 386 /* 387 * Call-back operations vector, so the netsmb module 388 * can notify smbfs about events affecting mounts. 389 * Installed in netsmb after smbfs loads. 390 * Note: smbfs only uses the fscb_discon hook. 391 */ 392 typedef struct smb_fscb { 393 /* Called when the VC has disconnected. */ 394 void (*fscb_disconn)(smb_share_t *); 395 /* Called when the VC has reconnected. */ 396 void (*fscb_connect)(smb_share_t *); 397 } smb_fscb_t; 398 /* Install the above vector, or pass NULL to clear it. */ 399 void smb_fscb_set(smb_fscb_t *); 400 401 /* 402 * The driver per open instance object. 403 * Mostly used in: smb_dev.c, smb_usr.c 404 */ 405 typedef struct smb_dev { 406 kmutex_t sd_lock; 407 struct smb_vc *sd_vc; /* Reference to VC */ 408 struct smb_share *sd_share; /* Reference to share if any */ 409 struct smb_fh *sd_fh; /* Reference to FH, if any */ 410 int sd_level; /* SMBL_VC, ... */ 411 int sd_vcgenid; /* Generation of share or VC */ 412 int sd_poll; /* Future use */ 413 int sd_flags; /* State of connection */ 414 #define NSMBFL_OPEN 0x0001 /* Device minor is open */ 415 #define NSMBFL_IOD 0x0004 /* Open by IOD */ 416 #define NSMBFL_IOCTL 0x0010 /* Serialize ioctl calls */ 417 zoneid_t zoneid; /* Zone id */ 418 } smb_dev_t; 419 420 extern const uint32_t nsmb_version; 421 422 /* 423 * smb_dev.c 424 */ 425 int smb_dev2share(int fd, struct smb_share **sspp); 426 427 428 /* 429 * smb_usr.c 430 */ 431 int smb_usr_ioctl(smb_dev_t *, int, intptr_t, int, cred_t *); 432 433 int smb_usr_get_flags2(smb_dev_t *sdp, intptr_t arg, int flags); 434 int smb_usr_get_ssnkey(smb_dev_t *sdp, intptr_t arg, int flags); 435 int smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags); 436 437 int smb_usr_simplerq(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr); 438 int smb_usr_t2request(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr); 439 440 int smb_usr_closefh(smb_dev_t *, cred_t *); 441 int smb_usr_rw(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr); 442 int smb_usr_ntcreate(smb_dev_t *, intptr_t, int, cred_t *); 443 int smb_usr_printjob(smb_dev_t *, intptr_t, int, cred_t *); 444 445 int smb_usr_get_ssn(smb_dev_t *, int, intptr_t, int, cred_t *); 446 int smb_usr_drop_ssn(smb_dev_t *sdp, int cmd); 447 448 int smb_usr_get_tree(smb_dev_t *, int, intptr_t, int, cred_t *); 449 int smb_usr_drop_tree(smb_dev_t *sdp, int cmd); 450 451 int smb_usr_iod_work(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr); 452 int smb_usr_iod_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, 453 cred_t *cr); 454 455 int smb_pkey_ioctl(int, intptr_t, int, cred_t *); 456 457 458 /* 459 * IOD functions 460 */ 461 int smb_iod_create(smb_vc_t *vcp); 462 int smb_iod_destroy(smb_vc_t *vcp); 463 void smb_iod_disconnect(smb_vc_t *vcp); 464 int smb2_iod_addrq(struct smb_rq *rqp); 465 int smb1_iod_addrq(struct smb_rq *rqp); 466 int smb1_iod_multirq(struct smb_rq *rqp); 467 int smb_iod_waitrq(struct smb_rq *rqp); 468 int smb_iod_waitrq_int(struct smb_rq *rqp); 469 void smb_iod_removerq(struct smb_rq *rqp); 470 int smb_iod_sendrecv(struct smb_rq *, int); 471 void smb_iod_shutdown_share(smb_share_t *ssp); 472 473 void smb_iod_sendall(smb_vc_t *); 474 int smb_iod_recvall(smb_vc_t *, boolean_t); 475 476 int nsmb_iod_connect(smb_vc_t *vcp, cred_t *cr); 477 int nsmb_iod_negotiate(smb_vc_t *vcp, cred_t *cr); 478 int nsmb_iod_ssnsetup(smb_vc_t *vcp, cred_t *cr); 479 int smb_iod_vc_work(smb_vc_t *, int, cred_t *); 480 int smb_iod_vc_idle(smb_vc_t *); 481 int smb_iod_vc_rcfail(smb_vc_t *); 482 int smb_iod_reconnect(smb_vc_t *); 483 484 /* 485 * Session level functions 486 */ 487 int smb_sm_init(void); 488 int smb_sm_idle(void); 489 void smb_sm_done(void); 490 491 /* 492 * VC level functions 493 */ 494 void smb_vc_hold(smb_vc_t *vcp); 495 void smb_vc_rele(smb_vc_t *vcp); 496 void smb_vc_kill(smb_vc_t *vcp); 497 498 int smb_vc_findcreate(smbioc_ossn_t *, smb_cred_t *, smb_vc_t **); 499 int smb_vc_create(smbioc_ossn_t *ossn, smb_cred_t *scred, smb_vc_t **vcpp); 500 501 const char *smb_vc_getpass(smb_vc_t *vcp); 502 uint16_t smb_vc_nextmid(smb_vc_t *vcp); 503 void *smb_vc_getipaddr(smb_vc_t *vcp, int *ipvers); 504 505 typedef void (*walk_share_func_t)(smb_share_t *); 506 void smb_vc_walkshares(struct smb_vc *, walk_share_func_t); 507 508 /* 509 * share level functions 510 */ 511 512 int smb_share_findcreate(smbioc_tcon_t *, smb_vc_t *, 513 smb_share_t **, smb_cred_t *); 514 515 void smb_share_hold(smb_share_t *ssp); 516 void smb_share_rele(smb_share_t *ssp); 517 void smb_share_kill(smb_share_t *ssp); 518 519 void smb_share_invalidate(smb_share_t *ssp); 520 int smb_share_tcon(smb_share_t *, smb_cred_t *); 521 522 /* 523 * File handle level functions 524 */ 525 int smb_fh_create(smb_share_t *ssp, struct smb_fh **fhpp); 526 void smb_fh_opened(struct smb_fh *fhp); 527 void smb_fh_close(struct smb_fh *fhp); 528 void smb_fh_hold(struct smb_fh *fhp); 529 void smb_fh_rele(struct smb_fh *fhp); 530 531 #endif /* _SMB_CONN_H */ 532