diff options
Diffstat (limited to 'sys/netsmb/smb_conn.h')
-rw-r--r-- | sys/netsmb/smb_conn.h | 464 |
1 files changed, 464 insertions, 0 deletions
diff --git a/sys/netsmb/smb_conn.h b/sys/netsmb/smb_conn.h new file mode 100644 index 0000000..3467f9a --- /dev/null +++ b/sys/netsmb/smb_conn.h @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2000-2001 Boris Popov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Boris Popov. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#ifndef _NETINET_IN_H_ +#include <netinet/in.h> +#endif + +/* + * Two levels of connection hierarchy + */ +#define SMBL_SM 0 +#define SMBL_VC 1 +#define SMBL_SHARE 2 +#define SMBL_NUM 3 +#define SMBL_NONE (-1) + +#define SMB_CS_NONE 0x0000 +#define SMB_CS_UPPER 0x0001 /* convert passed string to upper case */ +#define SMB_CS_LOWER 0x0002 /* convert passed string to lower case */ + +/* + * Common object flags + */ +#define SMBO_GONE 0x1000000 + +/* + * access modes + */ +#define SMBM_READ 0400 /* read conn attrs.(like list shares) */ +#define SMBM_WRITE 0200 /* modify conn attrs */ +#define SMBM_EXEC 0100 /* can send SMB requests */ +#define SMBM_READGRP 0040 +#define SMBM_WRITEGRP 0020 +#define SMBM_EXECGRP 0010 +#define SMBM_READOTH 0004 +#define SMBM_WRITEOTH 0002 +#define SMBM_EXECOTH 0001 +#define SMBM_MASK 0777 +#define SMBM_EXACT 010000 /* check for specified mode exactly */ +#define SMBM_ALL (SMBM_READ | SMBM_WRITE | SMBM_EXEC) +#define SMBM_DEFAULT (SMBM_READ | SMBM_WRITE | SMBM_EXEC) +#define SMBM_ANY_OWNER ((uid_t)-1) +#define SMBM_ANY_GROUP ((gid_t)-1) + +/* + * VC flags + */ +#define SMBV_PERMANENT 0x0002 +#define SMBV_LONGNAMES 0x0004 /* connection is configured to use long names */ +#define SMBV_ENCRYPT 0x0008 /* server asked for encrypted password */ +#define SMBV_WIN95 0x0010 /* used to apply bugfixes for this OS */ +#define SMBV_PRIVATE 0x0020 /* connection can be used only by creator */ +#define SMBV_RECONNECTING 0x0040 /* conn is in the process of reconnection */ +#define SMBV_SINGLESHARE 0x0080 /* only one share connectin should be allowed */ +#define SMBV_CREATE 0x0100 /* lookup for create opeartion */ +/*#define SMBV_FAILED 0x0200*/ /* last reconnect attempt has failed */ + + +/* + * smb_share flags + */ +#define SMBS_PERMANENT 0x0001 +#define SMBS_RECONNECTING 0x0002 +#define SMBS_CONNECTED 0x0004 + +/* + * share types + */ +#define SMB_ST_DISK 0x0 /* A: */ +#define SMB_ST_PRINTER 0x1 /* LPT: */ +#define SMB_ST_PIPE 0x2 /* IPC */ +#define SMB_ST_COMM 0x3 /* COMM */ +#define SMB_ST_ANY 0x4 +#define SMB_ST_MAX 0x4 +#define SMB_ST_NONE 0xff /* not a part of protocol */ + +/* + * Negotiated protocol parameters + */ +struct smb_sopt { + int sv_proto; + int16_t sv_tz; /* offset in min relative to UTC */ + u_int32_t sv_maxtx; /* maximum transmit buf size */ + u_char sv_sm; /* security mode */ + u_int16_t sv_maxmux; /* max number of outstanding rq's */ + u_int16_t sv_maxvcs; /* max number of VCs */ + u_int16_t sv_rawmode; + u_int32_t sv_maxraw; /* maximum raw-buffer size */ + u_int32_t sv_skey; /* session key */ + u_int32_t sv_caps; /* capabilites SMB_CAP_ */ +}; + +/* + * network IO daemon states + */ +enum smbiod_state { + SMBIOD_ST_NOTCONN, /* no connect request was made */ + SMBIOD_ST_RECONNECT, /* a [re]connect attempt is in progress */ + SMBIOD_ST_TRANACTIVE, /* transport level is up */ + SMBIOD_ST_VCACTIVE, /* session established */ + SMBIOD_ST_DEAD /* connection broken, transport is down */ +}; + + +/* + * Info structures + */ +#define SMB_INFO_NONE 0 +#define SMB_INFO_VC 2 +#define SMB_INFO_SHARE 3 + +struct smb_vc_info { + int itype; + int usecount; + uid_t uid; /* user id of connection */ + gid_t gid; /* group of connection */ + mode_t mode; /* access mode */ + int flags; + enum smbiod_state iodstate; + struct smb_sopt sopt; + char srvname[SMB_MAXSRVNAMELEN]; + char vcname[128]; +}; + +struct smb_share_info { + int itype; + int usecount; + u_short tid; /* TID */ + int type; /* share type */ + uid_t uid; /* user id of connection */ + gid_t gid; /* group of connection */ + mode_t mode; /* access mode */ + int flags; + char sname[128]; +}; + +#ifdef _KERNEL + +#include <sys/lock.h> +#include <netsmb/smb_subr.h> + +#define CONNADDREQ(a1,a2) ((a1)->sa_len == (a2)->sa_len && \ + bcmp(a1, a2, (a1)->sa_len) == 0) + +struct smb_vc; +struct smb_share; +struct smb_cred; +struct smb_rq; +struct mbdata; +struct smbioc_oshare; +struct smbioc_ossn; +struct uio; + +TAILQ_HEAD(smb_rqhead, smb_rq); + +#define SMB_DEFRQTIMO 5 + +#define SMB_DIALECT(vcp) ((vcp)->vc_sopt.sv_proto) + +struct smb_tran_desc; + +/* + * Connection object + */ +struct smb_connobj; + +typedef void smb_co_gone_t (struct smb_connobj *cp, struct smb_cred *scred); +typedef void smb_co_free_t (struct smb_connobj *cp); + +#define SMB_CO_LOCK(cp) smb_sl_lock(&(cp)->co_interlock) +#define SMB_CO_UNLOCK(cp) smb_sl_unlock(&(cp)->co_interlock) + +struct smb_connobj { + int co_level; /* SMBL_ */ + int co_flags; + struct lock co_lock; + struct smb_slock co_interlock; + int co_usecount; + struct smb_connobj * co_parent; + SLIST_HEAD(,smb_connobj)co_children; + SLIST_ENTRY(smb_connobj)co_next; + smb_co_gone_t * co_gone; + smb_co_free_t * co_free; +}; + +#define SMBCO_FOREACH(var, cp) SLIST_FOREACH((var), &(cp)->co_children, co_next) + +/* + * Virtual Circuit (session) to a server. + * This is the most (over)complicated part of SMB protocol. + * For the user security level (usl), each session with different remote + * user name has its own VC. + * It is unclear however, should share security level (ssl) allow additional + * VCs, because user name is not used and can be the same. On other hand, + * multiple VCs allows us to create separate sessions to server on a per + * user basis. + */ + +/* + * This lock protects vc_flags + */ +#define SMBC_ST_LOCK(vcp) smb_sl_lock(&(vcp)->vc_stlock) +#define SMBC_ST_UNLOCK(vcp) smb_sl_unlock(&(vcp)->vc_stlock) + + +struct smb_vc { + struct smb_connobj obj; + char * vc_srvname; + struct sockaddr*vc_paddr; /* server addr */ + struct sockaddr*vc_laddr; /* local addr, if any */ + char * vc_username; + char * vc_pass; /* password for usl case */ + char * vc_domain; /* workgroup/primary domain */ + + u_int vc_timo; /* default request timeout */ + int vc_maxvcs; /* maximum number of VC per connection */ + + void * vc_tolower; /* local charset */ + void * vc_toupper; /* local charset */ + void * vc_toserver; /* local charset to server one */ + void * vc_tolocal; /* server charset to local one */ + int vc_number; /* number of this VC from the client side */ + int vc_genid; + uid_t vc_uid; /* user id of connection */ + gid_t vc_grp; /* group of connection */ + mode_t vc_mode; /* access mode */ + struct tnode * vc_tnode; /* backing object */ + u_short vc_smbuid; /* unique vc id assigned by server */ + + u_char vc_hflags; /* or'ed with flags in the smb header */ + u_short vc_hflags2; /* or'ed with flags in the smb header */ + void * vc_tdata; /* transport control block */ + struct smb_tran_desc *vc_tdesc; + int vc_chlen; /* actual challenge length */ + u_char vc_ch[SMB_MAXCHALLENGELEN]; + u_short vc_mid; /* multiplex id */ + struct smb_sopt vc_sopt; /* server options */ + struct smb_cred*vc_scred; /* used in reconnect procedure */ + int vc_txmax; /* max tx/rx packet size */ + struct smbiod * vc_iod; + struct smb_slock vc_stlock; +}; + +#define vc_maxmux vc_sopt.sv_maxmux +#define vc_flags obj.co_flags + + +/* + * smb_share structure describes connection to the given SMB share (tree). + * Connection to share is always built on top of the VC. + */ + +/* + * This lock protects ss_flags + */ +#define SMBS_ST_LOCK(ssp) smb_sl_lock(&(ssp)->ss_stlock) +#define SMBS_ST_LOCKPTR(ssp) (&(ssp)->ss_stlock) +#define SMBS_ST_UNLOCK(ssp) smb_sl_unlock(&(ssp)->ss_stlock) + +struct smb_share { + struct smb_connobj obj; + char * ss_name; + u_short ss_tid; /* TID */ + int ss_type; /* share type */ + uid_t ss_uid; /* user id of connection */ + gid_t ss_grp; /* group of connection */ + mode_t ss_mode; /* access mode */ + int ss_vcgenid; + char * ss_pass; /* password to a share, can be null */ + struct smb_slock ss_stlock; + struct smb_cred *ss_cred; /* used in reconnect procedure */ +}; + +#define ss_flags obj.co_flags + +#define CPTOVC(cp) ((struct smb_vc*)(cp)) +#define VCTOCP(vcp) (&(vcp)->obj) +#define CPTOSS(cp) ((struct smb_share*)(cp)) +#define SSTOVC(ssp) CPTOVC(((ssp)->obj.co_parent)) +#define SSTOCP(ssp) (&(ssp)->obj) + +struct smb_vcspec { + char * srvname; + struct sockaddr*sap; + struct sockaddr*lap; + int flags; + char * username; + char * pass; + char * domain; + mode_t mode; + mode_t rights; + uid_t owner; + gid_t group; + char * localcs; + char * servercs; + struct smb_sharespec *shspec; + struct smb_share *ssp; /* returned */ + /* + * The rest is an internal data + */ + struct smb_cred *scred; +}; + +struct smb_sharespec { + char * name; + char * pass; + mode_t mode; + mode_t rights; + uid_t owner; + gid_t group; + int stype; + /* + * The rest is an internal data + */ + struct smb_cred *scred; +}; + +/* + * Session level functions + */ +int smb_sm_init(void); +int smb_sm_done(void); +int smb_sm_lookup(struct smb_vcspec *vcspec, + struct smb_sharespec *shspec, struct smb_cred *scred, + struct smb_vc **vcpp); + +/* + * Connection object + */ +void smb_co_ref(struct smb_connobj *cp, struct proc *p); +void smb_co_rele(struct smb_connobj *cp, struct smb_cred *scred); +int smb_co_get(struct smb_connobj *cp, int flags, struct smb_cred *scred); +void smb_co_put(struct smb_connobj *cp, struct smb_cred *scred); +int smb_co_lock(struct smb_connobj *cp, int flags, struct proc *p); +void smb_co_unlock(struct smb_connobj *cp, int flags, struct proc *p); + +/* + * session level functions + */ +int smb_vc_create(struct smb_vcspec *vcspec, + struct smb_cred *scred, struct smb_vc **vcpp); +int smb_vc_connect(struct smb_vc *vcp, struct smb_cred *scred); +int smb_vc_access(struct smb_vc *vcp, struct smb_cred *scred, mode_t mode); +int smb_vc_get(struct smb_vc *vcp, int flags, struct smb_cred *scred); +void smb_vc_put(struct smb_vc *vcp, struct smb_cred *scred); +void smb_vc_ref(struct smb_vc *vcp, struct proc *p); +void smb_vc_rele(struct smb_vc *vcp, struct smb_cred *scred); +int smb_vc_lock(struct smb_vc *vcp, int flags, struct proc *p); +void smb_vc_unlock(struct smb_vc *vcp, int flags, struct proc *p); +int smb_vc_lookupshare(struct smb_vc *vcp, struct smb_sharespec *shspec, + struct smb_cred *scred, struct smb_share **sspp); +const char * smb_vc_getpass(struct smb_vc *vcp); +u_short smb_vc_nextmid(struct smb_vc *vcp); + +/* + * share level functions + */ +int smb_share_create(struct smb_vc *vcp, struct smb_sharespec *shspec, + struct smb_cred *scred, struct smb_share **sspp); +int smb_share_access(struct smb_share *ssp, struct smb_cred *scred, mode_t mode); +void smb_share_ref(struct smb_share *ssp, struct proc *p); +void smb_share_rele(struct smb_share *ssp, struct smb_cred *scred); +int smb_share_get(struct smb_share *ssp, int flags, struct smb_cred *scred); +void smb_share_put(struct smb_share *ssp, struct smb_cred *scred); +int smb_share_lock(struct smb_share *ssp, int flags, struct proc *p); +void smb_share_unlock(struct smb_share *ssp, int flags, struct proc *p); +void smb_share_invalidate(struct smb_share *ssp); +int smb_share_valid(struct smb_share *ssp); +const char * smb_share_getpass(struct smb_share *ssp); + +/* + * SMB protocol level functions + */ +int smb_smb_negotiate(struct smb_vc *vcp, struct smb_cred *scred); +int smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred); +int smb_smb_ssnclose(struct smb_vc *vcp, struct smb_cred *scred); +int smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred); +int smb_smb_treedisconnect(struct smb_share *ssp, struct smb_cred *scred); +int smb_read(struct smb_share *ssp, u_int16_t fid, struct uio *uio, + struct smb_cred *scred); +int smb_write(struct smb_share *ssp, u_int16_t fid, struct uio *uio, + struct smb_cred *scred); +int smb_smb_echo(struct smb_vc *vcp, struct smb_cred *scred); + +/* + * smbiod thread + */ + +#define SMBIOD_EV_NEWRQ 0x0001 +#define SMBIOD_EV_SHUTDOWN 0x0002 +#define SMBIOD_EV_CONNECT 0x0003 +#define SMBIOD_EV_DISCONNECT 0x0004 +#define SMBIOD_EV_TREECONNECT 0x0005 +#define SMBIOD_EV_MASK 0x00ff +#define SMBIOD_EV_SYNC 0x0100 +#define SMBIOD_EV_PROCESSING 0x0200 + +struct smbiod_event { + int ev_type; + int ev_error; + void * ev_ident; + STAILQ_ENTRY(smbiod_event) ev_link; +}; + +#define SMBIOD_SHUTDOWN 0x0001 + +struct smbiod { + int iod_id; + int iod_flags; + enum smbiod_state iod_state; + int iod_muxcnt; /* number of active outstanding requests */ + int iod_sleeptimo; + struct smb_vc * iod_vc; + struct smb_slock iod_rqlock; /* iod_rqlist, iod_muxwant */ + struct smb_rqhead iod_rqlist; /* list of outstanding requests */ + int iod_muxwant; + struct proc * iod_p; + struct smb_cred iod_scred; + struct smb_slock iod_evlock; /* iod_evlist */ + STAILQ_HEAD(,smbiod_event) iod_evlist; + struct timespec iod_lastrqsent; + struct timespec iod_pingtimo; +}; + +int smb_iod_init(void); +int smb_iod_done(void); +int smb_iod_create(struct smb_vc *vcp); +int smb_iod_destroy(struct smbiod *iod); +int smb_iod_request(struct smbiod *iod, int event, void *ident); +int smb_iod_addrq(struct smb_rq *rqp); +int smb_iod_waitrq(struct smb_rq *rqp); +int smb_iod_removerq(struct smb_rq *rqp); + +#endif /* _KERNEL */ |