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