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 */
56typedef 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 inums */
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
105struct smb_rq;
106/* This declares struct smb_rqhead */
107TAILQ_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 */
130struct 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};
152typedef struct smb_connobj smb_connobj_t;
153
154/*
155 * "Level" in the connection object hierarchy
156 */
157enum 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 */
167struct smb_sopt {
168	uint16_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	uint32_t	sv2_capabilities;	/* capabilities */
182	uint32_t	sv2_maxtransact;	/* max transact size */
183	uint32_t	sv2_maxread;	/* max read size */
184	uint32_t	sv2_maxwrite;	/* max write size */
185	uint16_t	sv2_security_mode;	/* security mode */
186	uint8_t		sv2_guid[16];	/* GUID */
187};
188typedef struct smb_sopt smb_sopt_t;
189
190/*
191 * SMB1 I/O Deamon state
192 */
193struct smb_iods {
194	uint8_t		is_hflags;	/* SMB header flags */
195	uint16_t	is_hflags2;	/* SMB header flags2 */
196	uint16_t	is_smbuid;	/* SMB header UID */
197	uint16_t	is_next_mid;	/* SMB header MID */
198	uint32_t	is_txmax;	/* max tx/rx packet size */
199	uint32_t	is_rwmax;	/* max read/write data size */
200	uint32_t	is_rxmax;	/* max readx data size */
201	uint32_t	is_wxmax;	/* max writex data size */
202	/* Signing state */
203	uint32_t	is_next_seq;	/* my next sequence number */
204
205};
206typedef struct smb_iods smb_iods_t;
207
208/*
209 * Virtual Circuit to a server (really connection + session).
210 * Yes, calling this a "Virtual Circuit" is confusining,
211 * because it has nothing to do with the SMB notion of a
212 * "Virtual Circuit".
213 */
214typedef struct smb_vc {
215	struct smb_connobj	vc_co;	/* keep first! See CPTOVC */
216	enum smbiod_state	vc_state;
217	kcondvar_t		vc_statechg;
218
219	zoneid_t		vc_zoneid;
220	uid_t			vc_owner;	/* Unix owner */
221	int			vc_genid;	/* "generation" ID */
222
223	int			vc_mackeylen;	/* MAC key length */
224	int			vc_ssnkeylen;	/* session key length */
225	uint8_t			*vc_mackey;	/* MAC key buffer */
226	uint8_t			*vc_ssnkey;	/* session key buffer */
227	smb_sign_mech_t		vc_signmech;
228	struct smb_mac_ops	*vc_sign_ops;
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
310typedef 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
338typedef 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 */
346typedef 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 */
370typedef 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. */
377void 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 */
383typedef 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
398extern const uint32_t nsmb_version;
399
400/*
401 * smb_dev.c
402 */
403int  smb_dev2share(int fd, struct smb_share **sspp);
404
405
406/*
407 * smb_usr.c
408 */
409int smb_usr_ioctl(smb_dev_t *, int, intptr_t, int, cred_t *);
410
411int smb_usr_get_flags2(smb_dev_t *sdp, intptr_t arg, int flags);
412int smb_usr_get_ssnkey(smb_dev_t *sdp, intptr_t arg, int flags);
413int smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags);
414
415int smb_usr_simplerq(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
416int smb_usr_t2request(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
417
418int smb_usr_closefh(smb_dev_t *, cred_t *);
419int smb_usr_rw(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr);
420int smb_usr_ntcreate(smb_dev_t *, intptr_t, int, cred_t *);
421int smb_usr_printjob(smb_dev_t *, intptr_t, int, cred_t *);
422
423int smb_usr_get_ssn(smb_dev_t *, int, intptr_t, int, cred_t *);
424int smb_usr_drop_ssn(smb_dev_t *sdp, int cmd);
425
426int smb_usr_get_tree(smb_dev_t *, int, intptr_t, int, cred_t *);
427int smb_usr_drop_tree(smb_dev_t *sdp, int cmd);
428
429int smb_usr_iod_work(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
430int smb_usr_iod_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags,
431    cred_t *cr);
432
433int smb_pkey_ioctl(int, intptr_t, int, cred_t *);
434
435
436/*
437 * IOD functions
438 */
439int  smb_iod_create(smb_vc_t *vcp);
440int  smb_iod_destroy(smb_vc_t *vcp);
441void smb_iod_disconnect(smb_vc_t *vcp);
442int  smb2_iod_addrq(struct smb_rq *rqp);
443int  smb1_iod_addrq(struct smb_rq *rqp);
444int  smb1_iod_multirq(struct smb_rq *rqp);
445int  smb_iod_waitrq(struct smb_rq *rqp);
446int  smb_iod_waitrq_int(struct smb_rq *rqp);
447void smb_iod_removerq(struct smb_rq *rqp);
448int  smb_iod_sendrecv(struct smb_rq *, int);
449void smb_iod_shutdown_share(smb_share_t *ssp);
450
451void smb_iod_sendall(smb_vc_t *);
452int smb_iod_recvall(smb_vc_t *, boolean_t);
453
454int nsmb_iod_connect(smb_vc_t *vcp, cred_t *cr);
455int nsmb_iod_negotiate(smb_vc_t *vcp, cred_t *cr);
456int nsmb_iod_ssnsetup(smb_vc_t *vcp, cred_t *cr);
457int smb_iod_vc_work(smb_vc_t *, int, cred_t *);
458int smb_iod_vc_idle(smb_vc_t *);
459int smb_iod_vc_rcfail(smb_vc_t *);
460int smb_iod_reconnect(smb_vc_t *);
461
462/*
463 * Session level functions
464 */
465int  smb_sm_init(void);
466int  smb_sm_idle(void);
467void smb_sm_done(void);
468
469/*
470 * VC level functions
471 */
472void smb_vc_hold(smb_vc_t *vcp);
473void smb_vc_rele(smb_vc_t *vcp);
474void smb_vc_kill(smb_vc_t *vcp);
475
476int smb_vc_findcreate(smbioc_ossn_t *, smb_cred_t *, smb_vc_t **);
477int smb_vc_create(smbioc_ossn_t *ossn, smb_cred_t *scred, smb_vc_t **vcpp);
478
479const char *smb_vc_getpass(smb_vc_t *vcp);
480uint16_t smb_vc_nextmid(smb_vc_t *vcp);
481void *smb_vc_getipaddr(smb_vc_t *vcp, int *ipvers);
482
483typedef void (*walk_share_func_t)(smb_share_t *);
484void smb_vc_walkshares(struct smb_vc *,	walk_share_func_t);
485
486/*
487 * share level functions
488 */
489
490int smb_share_findcreate(smbioc_tcon_t *, smb_vc_t *,
491	smb_share_t **, smb_cred_t *);
492
493void smb_share_hold(smb_share_t *ssp);
494void smb_share_rele(smb_share_t *ssp);
495void smb_share_kill(smb_share_t *ssp);
496
497void smb_share_invalidate(smb_share_t *ssp);
498int  smb_share_tcon(smb_share_t *, smb_cred_t *);
499
500/*
501 * File handle level functions
502 */
503int smb_fh_create(smb_share_t *ssp, struct smb_fh **fhpp);
504void smb_fh_opened(struct smb_fh *fhp);
505void smb_fh_close(struct smb_fh *fhp);
506void smb_fh_hold(struct smb_fh *fhp);
507void smb_fh_rele(struct smb_fh *fhp);
508
509#endif /* _SMB_CONN_H */
510