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