smb_conn.h revision 11332:ed3411181494
1254401Scy/* 2254401Scy * Copyright (c) 2000-2001 Boris Popov 3254401Scy * All rights reserved. 4254401Scy * 5254401Scy * Redistribution and use in source and binary forms, with or without 6254401Scy * modification, are permitted provided that the following conditions 7254401Scy * are met: 8255332Scy * 1. Redistributions of source code must retain the above copyright 9254401Scy * notice, this list of conditions and the following disclaimer. 10255332Scy * 2. Redistributions in binary form must reproduce the above copyright 11254401Scy * notice, this list of conditions and the following disclaimer in the 12254401Scy * documentation and/or other materials provided with the distribution. 13254401Scy * 3. All advertising materials mentioning features or use of this software 14254401Scy * must display the following acknowledgement: 15254401Scy * This product includes software developed by Boris Popov. 16254401Scy * 4. Neither the name of the author nor the names of any co-contributors 17254401Scy * may be used to endorse or promote products derived from this software 18254401Scy * without specific prior written permission. 19254401Scy * 20254401Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21254401Scy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22254401Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23254401Scy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24254401Scy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25255332Scy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26254401Scy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27254401Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28254401Scy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29254401Scy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30255332Scy * SUCH DAMAGE. 31254401Scy * 32254401Scy * $Id: smb_conn.h,v 1.32.42.1 2005/05/27 02:35:29 lindak Exp $ 33254401Scy */ 34254401Scy 35254401Scy/* 36254401Scy * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 37254401Scy * Use is subject to license terms. 38254401Scy */ 39254401Scy 40254401Scy#ifndef _SMB_CONN_H 41254401Scy#define _SMB_CONN_H 42254401Scy 43254401Scy#include <sys/dditypes.h> 44254401Scy#include <sys/t_lock.h> 45254401Scy#include <sys/queue.h> /* for SLIST below */ 46254401Scy#include <sys/uio.h> 47254401Scy#include <netsmb/smb_dev.h> 48254401Scy 49254401Scy/* 50254401Scy * Credentials of user/process for processing in the connection procedures 51254401Scy */ 52254401Scytypedef struct smb_cred { 53254401Scy struct cred *scr_cred; 54255332Scy} smb_cred_t; 55254401Scy 56254401Scy/* 57254401Scy * Common object flags 58254401Scy */ 59254401Scy#define SMBO_GONE 0x1000000 60255332Scy 61254401Scy/* 62254401Scy * Bits in vc_flags (a.k.a. vc_co.co_flags) 63254401Scy * Many of these were duplicates of SMBVOPT_ flags 64255332Scy * and we now keep those too instead of merging 65254401Scy * them into vc_flags. 66254401Scy */ 67254401Scy 68254401Scy#define SMBV_WIN95 0x0010 /* used to apply bugfixes for this OS */ 69254401Scy#define SMBV_NT4 0x0020 /* used when NT4 issues invalid resp */ 70254401Scy#define SMBV_UNICODE 0x0040 /* conn configured to use Unicode */ 71254401Scy 72254401Scy/* 73254401Scy * Note: the common "obj" level uses this GONE flag by 74254401Scy * the name SMBO_GONE. Keep this alias as a reminder. 75254401Scy */ 76254401Scy#define SMBV_GONE SMBO_GONE 77254401Scy 78254401Scy/* 79254401Scy * bits in smb_share ss_flags (a.k.a. ss_co.co_flags) 80254401Scy */ 81254401Scy#define SMBS_RECONNECTING 0x0002 82254401Scy#define SMBS_CONNECTED 0x0004 83254401Scy#define SMBS_TCON_WAIT 0x0008 84254401Scy#define SMBS_FST_FAT 0x0010 /* share FS Type is FAT */ 85254401Scy/* 86254401Scy * Note: the common "obj" level uses this GONE flag by 87254401Scy * the name SMBO_GONE. Keep this alias as a reminder. 88254401Scy */ 89254401Scy#define SMBS_GONE SMBO_GONE 90254401Scy 91254401Scystruct smb_rq; 92254401Scy/* This declares struct smb_rqhead */ 93254401ScyTAILQ_HEAD(smb_rqhead, smb_rq); 94254401Scy 95254401Scy#define SMB_NBTIMO 15 96254401Scy#define SMB_DEFRQTIMO 30 /* 30 for oplock revoke/writeback */ 97254401Scy#define SMBWRTTIMO 60 98254401Scy#define SMBSSNSETUPTIMO 60 99254401Scy#define SMBNOREPLYWAIT (0) 100254401Scy 101254401Scy#define SMB_DIALECT(vcp) ((vcp)->vc_sopt.sv_proto) 102254401Scy 103254401Scy/* 104254401Scy * Connection object 105254401Scy */ 106254401Scy 107254401Scy#define SMB_CO_LOCK(cp) mutex_enter(&(cp)->co_lock) 108254401Scy#define SMB_CO_UNLOCK(cp) mutex_exit(&(cp)->co_lock) 109254401Scy 110254401Scy/* 111254401Scy * Common part of smb_vc, smb_share 112254401Scy * Locking: co_lock protects most 113254401Scy * fields in this struct, except 114254401Scy * as noted below: 115254401Scy */ 116254401Scystruct smb_connobj { 117254401Scy kmutex_t co_lock; 118254401Scy int co_level; /* SMBL_ */ 119254401Scy int co_flags; 120254401Scy int co_usecount; 121254401Scy 122254401Scy /* Note: must lock co_parent before child. */ 123254401Scy struct smb_connobj *co_parent; 124254401Scy 125254401Scy /* this.co_lock protects the co_children list */ 126254401Scy SLIST_HEAD(, smb_connobj) co_children; 127254401Scy 128254401Scy /* 129254401Scy * Linkage in parent's list of children. 130254401Scy * Must hold parent.co_lock to traverse. 131254401Scy */ 132254401Scy SLIST_ENTRY(smb_connobj) co_next; 133254401Scy 134254401Scy /* These two are set only at creation. */ 135254401Scy void (*co_gone)(struct smb_connobj *); 136254401Scy void (*co_free)(struct smb_connobj *); 137254401Scy}; 138254401Scytypedef struct smb_connobj smb_connobj_t; 139254401Scy 140254401Scy/* 141254401Scy * "Level" in the connection object hierarchy 142254401Scy */ 143254401Scy#define SMBL_SM 0 144254401Scy#define SMBL_VC 1 145254401Scy#define SMBL_SHARE 2 146254401Scy 147254401Scy/* 148254401Scy * Virtual Circuit to a server (really connection + session). 149254401Scy * Yes, calling this a "Virtual Circuit" is confusining, 150254401Scy * because it has nothing to do with the SMB notion of a 151254401Scy * "Virtual Circuit". 152254401Scy */ 153254401Scytypedef struct smb_vc { 154254401Scy struct smb_connobj vc_co; /* keep first! See CPTOVC */ 155254401Scy enum smbiod_state vc_state; 156254401Scy kcondvar_t vc_statechg; 157254401Scy 158254401Scy zoneid_t vc_zoneid; 159254401Scy uid_t vc_owner; /* Unix owner */ 160254401Scy int vc_genid; /* "generation" ID */ 161254401Scy 162254401Scy int vc_mackeylen; /* length of MAC key */ 163254401Scy uint8_t *vc_mackey; /* MAC key */ 164254401Scy 165254401Scy ksema_t vc_sendlock; 166254401Scy struct smb_tran_desc *vc_tdesc; /* transport ops. vector */ 167254401Scy void *vc_tdata; /* transport control block */ 168254401Scy 169254401Scy kcondvar_t iod_idle; /* IOD thread idle CV */ 170254401Scy krwlock_t iod_rqlock; /* iod_rqlist */ 171254401Scy struct smb_rqhead iod_rqlist; /* list of outstanding reqs */ 172254401Scy struct _kthread *iod_thr; /* the IOD (reader) thread */ 173254401Scy int iod_flags; /* see SMBIOD_* below */ 174254401Scy int iod_newrq; /* send needed (iod_rqlock) */ 175254401Scy int iod_muxfull; /* maxmux limit reached */ 176254401Scy 177254401Scy /* This is copied in/out when IOD enters/returns */ 178254401Scy smbioc_ssn_work_t vc_work; 179254401Scy 180254401Scy /* session identity, etc. */ 181254401Scy smbioc_ossn_t vc_ssn; 182254401Scy} smb_vc_t; 183254401Scy 184254401Scy#define vc_lock vc_co.co_lock 185254401Scy#define vc_flags vc_co.co_flags 186254401Scy 187254401Scy/* defines for members in vc_ssn */ 188254401Scy#define vc_owner vc_ssn.ssn_owner 189254401Scy#define vc_srvname vc_ssn.ssn_srvname 190254401Scy#define vc_srvaddr vc_ssn.ssn_id.id_srvaddr 191254401Scy#define vc_domain vc_ssn.ssn_id.id_domain 192254401Scy#define vc_username vc_ssn.ssn_id.id_user 193254401Scy#define vc_vopt vc_ssn.ssn_vopt 194254401Scy 195254401Scy/* defines for members in vc_work */ 196254401Scy#define vc_sopt vc_work.wk_sopt 197254401Scy#define vc_maxmux vc_work.wk_sopt.sv_maxmux 198254401Scy#define vc_tran_fd vc_work.wk_iods.is_tran_fd 199254401Scy#define vc_hflags vc_work.wk_iods.is_hflags 200254401Scy#define vc_hflags2 vc_work.wk_iods.is_hflags2 201254401Scy#define vc_smbuid vc_work.wk_iods.is_smbuid 202254401Scy#define vc_next_mid vc_work.wk_iods.is_next_mid 203254401Scy#define vc_txmax vc_work.wk_iods.is_txmax 204254401Scy#define vc_rwmax vc_work.wk_iods.is_rwmax 205254401Scy#define vc_rxmax vc_work.wk_iods.is_rxmax 206254401Scy#define vc_wxmax vc_work.wk_iods.is_wxmax 207254401Scy#define vc_ssn_key vc_work.wk_iods.is_ssn_key 208254401Scy#define vc_next_seq vc_work.wk_iods.is_next_seq 209254401Scy#define vc_u_mackey vc_work.wk_iods.is_u_mackey 210254401Scy#define vc_u_maclen vc_work.wk_iods.is_u_maclen 211254401Scy 212254401Scy#define SMB_VC_LOCK(vcp) mutex_enter(&(vcp)->vc_lock) 213254401Scy#define SMB_VC_UNLOCK(vcp) mutex_exit(&(vcp)->vc_lock) 214254401Scy 215254401Scy#define SMB_UNICODE_STRINGS(vcp) ((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE) 216254401Scy 217254401Scy/* Bits in iod_flags */ 218254401Scy#define SMBIOD_RUNNING 0x0001 219254401Scy#define SMBIOD_SHUTDOWN 0x0002 220254401Scy 221254401Scy/* 222254401Scy * smb_share structure describes connection to the given SMB share (tree). 223254401Scy * Connection to share is always built on top of the VC. 224254401Scy */ 225254401Scy 226254401Scytypedef struct smb_share { 227254401Scy struct smb_connobj ss_co; /* keep first! See CPTOSS */ 228254401Scy kcondvar_t ss_conn_done; /* wait for reconnect */ 229254401Scy int ss_conn_waiters; 230254401Scy int ss_vcgenid; /* check VC generation ID */ 231254401Scy uint16_t ss_tid; /* TID */ 232254401Scy uint16_t ss_options; /* option support bits */ 233254401Scy smbioc_oshare_t ss_ioc; 234254401Scy} smb_share_t; 235254401Scy 236254401Scy#define ss_lock ss_co.co_lock 237254401Scy#define ss_flags ss_co.co_flags 238254401Scy 239254401Scy#define ss_name ss_ioc.sh_name 240254401Scy#define ss_pwlen ss_ioc.sh_pwlen 241254401Scy#define ss_pass ss_ioc.sh_pass 242254401Scy#define ss_type_req ss_ioc.sh_type_req 243254401Scy#define ss_type_ret ss_ioc.sh_type_ret 244254401Scy 245254401Scy#define SMB_SS_LOCK(ssp) mutex_enter(&(ssp)->ss_lock) 246254401Scy#define SMB_SS_UNLOCK(ssp) mutex_exit(&(ssp)->ss_lock) 247254401Scy 248254401Scy#define CPTOVC(cp) ((struct smb_vc *)((void *)(cp))) 249254401Scy#define VCTOCP(vcp) (&(vcp)->vc_co) 250254401Scy 251254401Scy#define CPTOSS(cp) ((struct smb_share *)((void *)(cp))) 252254401Scy#define SSTOVC(ssp) CPTOVC(((ssp)->ss_co.co_parent)) 253254401Scy#define SSTOCP(ssp) (&(ssp)->ss_co) 254254401Scy 255254401Scy/* 256254401Scy * Call-back operations vector, so the netsmb module 257254401Scy * can notify smbfs about events affecting mounts. 258254401Scy * Installed in netsmb after smbfs loads. 259254401Scy */ 260254401Scytypedef struct smb_fscb { 261254401Scy /* Called when the VC has disconnected. */ 262254401Scy void (*fscb_disconn)(smb_share_t *); 263254401Scy /* Called when the VC has reconnected. */ 264254401Scy void (*fscb_connect)(smb_share_t *); 265254401Scy /* Called when the server becomes unresponsive. */ 266254401Scy void (*fscb_down)(smb_share_t *); 267254401Scy /* Called when the server is responding again. */ 268254401Scy void (*fscb_up)(smb_share_t *); 269254401Scy} smb_fscb_t; 270254401Scy/* Install the above vector, or pass NULL to clear it. */ 271254401Scyvoid smb_fscb_set(smb_fscb_t *); 272254401Scy 273254401Scy/* 274254401Scy * The driver per open instance object. 275254401Scy * Mostly used in: smb_dev.c, smb_usr.c 276254401Scy */ 277254401Scytypedef struct smb_dev { 278254401Scy int sd_opened; /* Opened or not */ 279254401Scy int sd_level; /* Future use */ 280254401Scy struct smb_vc *sd_vc; /* Reference to VC */ 281254401Scy struct smb_share *sd_share; /* Reference to share if any */ 282254401Scy int sd_vcgenid; /* Generation of share or VC */ 283254401Scy int sd_poll; /* Future use */ 284254401Scy int sd_seq; /* Kind of minor number/instance no */ 285254401Scy int sd_flags; /* State of connection */ 286254401Scy#define NSMBFL_OPEN 0x0001 287254401Scy#define NSMBFL_IOD 0x0002 288254401Scy zoneid_t zoneid; /* Zone id */ 289254401Scy dev_info_t *smb_dip; /* ptr to dev_info node */ 290254401Scy void *sd_devfs; /* Dont know how to use this. but */ 291254401Scy struct cred *smb_cred; /* per dev credentails. Future use */ 292254401Scy} smb_dev_t; 293254401Scy 294254401Scyextern const uint32_t nsmb_version; 295254401Scy 296254401Scy/* 297254401Scy * smb_dev.c 298254401Scy */ 299254401Scyint smb_dev2share(int fd, struct smb_share **sspp); 300254401Scy 301254401Scy 302254401Scy/* 303254401Scy * smb_usr.c 304254401Scy */ 305254401Scyint smb_usr_get_flags2(smb_dev_t *sdp, intptr_t arg, int flags); 306254401Scyint smb_usr_get_ssnkey(smb_dev_t *sdp, intptr_t arg, int flags); 307254401Scy 308254401Scyint smb_usr_simplerq(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr); 309254401Scyint smb_usr_t2request(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr); 310254401Scyint smb_usr_rw(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr); 311254401Scy 312254401Scyint smb_usr_get_ssn(smb_dev_t *, int, intptr_t, int, cred_t *); 313254401Scyint smb_usr_drop_ssn(smb_dev_t *sdp, int cmd); 314254401Scy 315254401Scyint smb_usr_get_tree(smb_dev_t *, int, intptr_t, int, cred_t *); 316254401Scyint smb_usr_drop_tree(smb_dev_t *sdp, int cmd); 317254401Scy 318254401Scyint smb_usr_iod_work(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr); 319254401Scyint smb_usr_iod_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags); 320254401Scy 321254401Scy 322254401Scy/* 323254401Scy * IOD functions 324254401Scy */ 325254401Scyint smb_iod_create(smb_vc_t *vcp); 326254401Scyint smb_iod_destroy(smb_vc_t *vcp); 327254401Scyint smb_iod_connect(smb_vc_t *vcp); 328254401Scyvoid smb_iod_disconnect(smb_vc_t *vcp); 329254401Scyint smb_iod_addrq(struct smb_rq *rqp); 330254401Scyint smb_iod_multirq(struct smb_rq *rqp); 331254401Scyint smb_iod_waitrq(struct smb_rq *rqp); 332254401Scyvoid smb_iod_removerq(struct smb_rq *rqp); 333254401Scyvoid smb_iod_shutdown_share(smb_share_t *ssp); 334254401Scy 335254401Scyvoid smb_iod_sendall(smb_vc_t *); 336254401Scyint smb_iod_recvall(smb_vc_t *); 337254401Scy 338254401Scyint smb_iod_vc_work(smb_vc_t *, cred_t *); 339254401Scyint smb_iod_vc_idle(smb_vc_t *); 340254401Scyint smb_iod_vc_rcfail(smb_vc_t *); 341254401Scyint smb_iod_reconnect(smb_vc_t *); 342254401Scy 343254401Scy/* 344254401Scy * Session level functions 345254401Scy */ 346254401Scyint smb_sm_init(void); 347254401Scyint smb_sm_idle(void); 348254401Scyvoid smb_sm_done(void); 349254401Scy 350254401Scy/* 351254401Scy * VC level functions 352254401Scy */ 353254401Scyvoid smb_vc_hold(smb_vc_t *vcp); 354254401Scyvoid smb_vc_rele(smb_vc_t *vcp); 355254401Scyvoid smb_vc_kill(smb_vc_t *vcp); 356254401Scy 357254401Scyint smb_vc_findcreate(smbioc_ossn_t *, smb_cred_t *, smb_vc_t **); 358254401Scyint smb_vc_create(smbioc_ossn_t *ossn, smb_cred_t *scred, smb_vc_t **vcpp); 359254401Scy 360254401Scyconst char *smb_vc_getpass(smb_vc_t *vcp); 361254401Scyuint16_t smb_vc_nextmid(smb_vc_t *vcp); 362254401Scyvoid *smb_vc_getipaddr(smb_vc_t *vcp, int *ipvers); 363254401Scy 364254401Scytypedef void (*walk_share_func_t)(smb_share_t *); 365254401Scyvoid smb_vc_walkshares(struct smb_vc *, walk_share_func_t); 366254401Scy 367254401Scy/* 368254401Scy * share level functions 369254401Scy */ 370254401Scy 371254401Scyint smb_share_findcreate(smbioc_tcon_t *, smb_vc_t *, 372254401Scy smb_share_t **, smb_cred_t *); 373254401Scy 374254401Scyvoid smb_share_hold(smb_share_t *ssp); 375254401Scyvoid smb_share_rele(smb_share_t *ssp); 376254401Scyvoid smb_share_kill(smb_share_t *ssp); 377254401Scy 378254401Scyvoid smb_share_invalidate(smb_share_t *ssp); 379254401Scyint smb_share_tcon(smb_share_t *, smb_cred_t *); 380254401Scy 381254401Scy/* 382254401Scy * SMB protocol level functions 383254401Scy */ 384254401Scyint smb_smb_echo(smb_vc_t *vcp, smb_cred_t *scred, int timo); 385254401Scyint smb_smb_treeconnect(smb_share_t *ssp, smb_cred_t *scred); 386254401Scyint smb_smb_treedisconnect(smb_share_t *ssp, smb_cred_t *scred); 387254401Scy 388254401Scyint smb_rwuio(smb_share_t *ssp, uint16_t fid, uio_rw_t rw, 389254401Scy uio_t *uiop, smb_cred_t *scred, int timo); 390254401Scy 391254401Scy#endif /* _SMB_CONN_H */ 392254401Scy