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  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
40  */
41 
42 #ifndef _SMB_CONN_H
43 #define	_SMB_CONN_H
44 
45 #include <sys/dditypes.h>
46 #include <sys/t_lock.h>
47 #include <sys/queue.h> /* for SLIST below */
48 #include <sys/uio.h>
49 #include <netsmb/smb_dev.h>
50 
51 /*
52  * Credentials of user/process for processing in the connection procedures
53  */
54 typedef struct smb_cred {
55 	struct cred *scr_cred;
56 } smb_cred_t;
57 
58 /*
59  * Common object flags
60  */
61 #define	SMBO_GONE		0x1000000
62 
63 /*
64  * Bits in vc_flags (a.k.a. vc_co.co_flags)
65  * Note: SMBO_GONE is also in vc_flags
66  */
67 #define	SMBV_UNICODE		0x0040	/* conn configured to use Unicode */
68 #define	SMBV_EXT_SEC		0x0080	/* conn to use extended security */
69 #define	SMBV_WILL_SIGN		0x0100	/* negotiated signing */
70 
71 /*
72  * Note: the common "obj" level uses this GONE flag by
73  * the name SMBO_GONE.  Keep this alias as a reminder.
74  */
75 #define	SMBV_GONE		SMBO_GONE
76 
77 /*
78  * bits in smb_share ss_flags (a.k.a. ss_co.co_flags)
79  */
80 #define	SMBS_RECONNECTING	0x0002
81 #define	SMBS_CONNECTED		0x0004
82 #define	SMBS_TCON_WAIT		0x0008
83 #define	SMBS_FST_FAT		0x0010	/* share FS Type is FAT */
84 /*
85  * Note: the common "obj" level uses this GONE flag by
86  * the name SMBO_GONE.  Keep this alias as a reminder.
87  */
88 #define	SMBS_GONE		SMBO_GONE
89 
90 struct smb_rq;
91 /* This declares struct smb_rqhead */
92 TAILQ_HEAD(smb_rqhead, smb_rq);
93 
94 #define	SMB_NBTIMO	15
95 #define	SMB_DEFRQTIMO	30	/* 30 for oplock revoke/writeback */
96 #define	SMBWRTTIMO	60
97 #define	SMBSSNSETUPTIMO	60
98 #define	SMBNOREPLYWAIT (0)
99 
100 #define	SMB_DIALECT(vcp)	((vcp)->vc_sopt.sv_proto)
101 
102 /*
103  * Connection object
104  */
105 
106 #define	SMB_CO_LOCK(cp)		mutex_enter(&(cp)->co_lock)
107 #define	SMB_CO_UNLOCK(cp)	mutex_exit(&(cp)->co_lock)
108 
109 /*
110  * Common part of smb_vc, smb_share
111  * Locking: co_lock protects most
112  * fields in this struct, except
113  * as noted below:
114  */
115 struct smb_connobj {
116 	kmutex_t		co_lock;
117 	int			co_level;	/* SMBL_ */
118 	int			co_flags;
119 	int			co_usecount;
120 
121 	/* Note: must lock co_parent before child. */
122 	struct smb_connobj	*co_parent;
123 
124 	/* this.co_lock protects the co_children list */
125 	SLIST_HEAD(, smb_connobj) co_children;
126 
127 	/*
128 	 * Linkage in parent's list of children.
129 	 * Must hold parent.co_lock to traverse.
130 	 */
131 	SLIST_ENTRY(smb_connobj) co_next;
132 
133 	/* These two are set only at creation. */
134 	void (*co_gone)(struct smb_connobj *);
135 	void (*co_free)(struct smb_connobj *);
136 };
137 typedef struct smb_connobj smb_connobj_t;
138 
139 /*
140  * "Level" in the connection object hierarchy
141  */
142 #define	SMBL_SM		0
143 #define	SMBL_VC		1
144 #define	SMBL_SHARE	2
145 
146 /*
147  * SMB1 Negotiated protocol parameters
148  */
149 struct smb_sopt {
150 	int16_t		sv_proto;	/* protocol dialect */
151 	uchar_t		sv_sm;		/* security mode */
152 	int16_t		sv_tz;		/* offset in min relative to UTC */
153 	uint16_t	sv_maxmux;	/* max number of outstanding rq's */
154 	uint16_t	sv_maxvcs;	/* max number of VCs */
155 	uint16_t	sv_rawmode;
156 	uint32_t	sv_maxtx;	/* maximum transmit buf size */
157 	uint32_t	sv_maxraw;	/* maximum raw-buffer size */
158 	uint32_t	sv_skey;	/* session key */
159 	uint32_t	sv_caps;	/* capabilites SMB_CAP_ */
160 };
161 typedef struct smb_sopt smb_sopt_t;
162 
163 /*
164  * SMB1 I/O Deamon state
165  */
166 struct smb_iods {
167 	uint8_t		is_hflags;	/* SMB header flags */
168 	uint16_t	is_hflags2;	/* SMB header flags2 */
169 	uint16_t	is_smbuid;	/* SMB header UID */
170 	uint16_t	is_next_mid;	/* SMB header MID */
171 	uint32_t	is_txmax;	/* max tx/rx packet size */
172 	uint32_t	is_rwmax;	/* max read/write data size */
173 	uint32_t	is_rxmax;	/* max readx data size */
174 	uint32_t	is_wxmax;	/* max writex data size */
175 	/* Signing state */
176 	uint32_t	is_next_seq;	/* my next sequence number */
177 
178 };
179 typedef struct smb_iods smb_iods_t;
180 
181 /*
182  * Virtual Circuit to a server (really connection + session).
183  * Yes, calling this a "Virtual Circuit" is confusining,
184  * because it has nothing to do with the SMB notion of a
185  * "Virtual Circuit".
186  */
187 typedef struct smb_vc {
188 	struct smb_connobj	vc_co;	/* keep first! See CPTOVC */
189 	enum smbiod_state	vc_state;
190 	kcondvar_t		vc_statechg;
191 
192 	zoneid_t		vc_zoneid;
193 	uid_t			vc_owner;	/* Unix owner */
194 	int			vc_genid;	/* "generation" ID */
195 
196 	int			vc_mackeylen;	/* MAC key length */
197 	int			vc_ssnkeylen;	/* session key length */
198 	uint8_t			*vc_mackey;	/* MAC key buffer */
199 	uint8_t			*vc_ssnkey;	/* session key buffer */
200 
201 	ksema_t			vc_sendlock;
202 	struct smb_tran_desc	*vc_tdesc;	/* transport ops. vector */
203 	void			*vc_tdata;	/* transport control block */
204 
205 	kcondvar_t		iod_idle;	/* IOD thread idle CV */
206 	krwlock_t		iod_rqlock;	/* iod_rqlist */
207 	struct smb_rqhead	iod_rqlist;	/* list of outstanding reqs */
208 	struct _kthread		*iod_thr;	/* the IOD (reader) thread */
209 	int			iod_flags;	/* see SMBIOD_* below */
210 	int			iod_newrq;	/* send needed (iod_rqlock) */
211 	int			iod_muxfull;	/* maxmux limit reached */
212 
213 	smb_iods_t		vc_iods;
214 	smb_sopt_t		vc_sopt;
215 
216 	/* This is copied in/out when IOD enters/returns */
217 	smbioc_ssn_work_t	vc_work;
218 
219 	/* session identity, etc. */
220 	smbioc_ossn_t		vc_ssn;
221 } smb_vc_t;
222 
223 #define	vc_lock		vc_co.co_lock
224 #define	vc_flags	vc_co.co_flags
225 
226 /* defines for members in vc_ssn */
227 #define	vc_owner	vc_ssn.ssn_owner
228 #define	vc_srvname	vc_ssn.ssn_srvname
229 #define	vc_srvaddr	vc_ssn.ssn_id.id_srvaddr
230 #define	vc_domain	vc_ssn.ssn_id.id_domain
231 #define	vc_username	vc_ssn.ssn_id.id_user
232 #define	vc_vopt		vc_ssn.ssn_vopt
233 
234 /* defines for members in vc_work */
235 
236 /* defines for members in vc_sopt ? */
237 #define	vc_maxmux	vc_sopt.sv_maxmux
238 
239 /* defines for members in vc_iods */
240 #define	vc_hflags	vc_iods.is_hflags
241 #define	vc_hflags2	vc_iods.is_hflags2
242 #define	vc_smbuid	vc_iods.is_smbuid
243 #define	vc_next_mid	vc_iods.is_next_mid
244 #define	vc_txmax	vc_iods.is_txmax
245 #define	vc_rwmax	vc_iods.is_rwmax
246 #define	vc_rxmax	vc_iods.is_rxmax
247 #define	vc_wxmax	vc_iods.is_wxmax
248 #define	vc_next_seq	vc_iods.is_next_seq
249 
250 #define	SMB_VC_LOCK(vcp)	mutex_enter(&(vcp)->vc_lock)
251 #define	SMB_VC_UNLOCK(vcp)	mutex_exit(&(vcp)->vc_lock)
252 
253 #define	SMB_UNICODE_STRINGS(vcp)	((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE)
254 
255 /* Bits in iod_flags */
256 #define	SMBIOD_RUNNING		0x0001
257 #define	SMBIOD_SHUTDOWN		0x0002
258 
259 /*
260  * smb_share structure describes connection to the given SMB share (tree).
261  * Connection to share is always built on top of the VC.
262  */
263 
264 typedef struct smb_share {
265 	struct smb_connobj ss_co;	/* keep first! See CPTOSS */
266 	kcondvar_t	ss_conn_done;	/* wait for reconnect */
267 	int		ss_conn_waiters;
268 	int		ss_vcgenid;	/* check VC generation ID */
269 	uint16_t	ss_tid;		/* TID */
270 	uint16_t	ss_options;	/* option support bits */
271 	smbioc_oshare_t ss_ioc;
272 } smb_share_t;
273 
274 #define	ss_lock		ss_co.co_lock
275 #define	ss_flags	ss_co.co_flags
276 
277 #define	ss_use		ss_ioc.sh_use
278 #define	ss_type		ss_ioc.sh_type
279 #define	ss_name		ss_ioc.sh_name
280 #define	ss_pass		ss_ioc.sh_pass
281 
282 #define	SMB_SS_LOCK(ssp)	mutex_enter(&(ssp)->ss_lock)
283 #define	SMB_SS_UNLOCK(ssp)	mutex_exit(&(ssp)->ss_lock)
284 
285 #define	CPTOVC(cp)	((struct smb_vc *)((void *)(cp)))
286 #define	VCTOCP(vcp)	(&(vcp)->vc_co)
287 
288 #define	CPTOSS(cp)	((struct smb_share *)((void *)(cp)))
289 #define	SSTOVC(ssp)	CPTOVC(((ssp)->ss_co.co_parent))
290 #define	SSTOCP(ssp)	(&(ssp)->ss_co)
291 
292 /*
293  * Call-back operations vector, so the netsmb module
294  * can notify smbfs about events affecting mounts.
295  * Installed in netsmb after smbfs loads.
296  */
297 typedef struct smb_fscb {
298 	/* Called when the VC has disconnected. */
299 	void (*fscb_disconn)(smb_share_t *);
300 	/* Called when the VC has reconnected. */
301 	void (*fscb_connect)(smb_share_t *);
302 	/* Called when the server becomes unresponsive. */
303 	void (*fscb_down)(smb_share_t *);
304 	/* Called when the server is responding again. */
305 	void (*fscb_up)(smb_share_t *);
306 } smb_fscb_t;
307 /* Install the above vector, or pass NULL to clear it. */
308 void smb_fscb_set(smb_fscb_t *);
309 
310 /*
311  * The driver per open instance object.
312  * Mostly used in: smb_dev.c, smb_usr.c
313  */
314 typedef struct smb_dev {
315 	kmutex_t	sd_lock;
316 	struct smb_vc	*sd_vc;		/* Reference to VC */
317 	struct smb_share *sd_share;	/* Reference to share if any */
318 	int		sd_level;	/* SMBL_VC, ... */
319 	int		sd_vcgenid;	/* Generation of share or VC */
320 	int		sd_poll;	/* Future use */
321 	int		sd_flags;	/* State of connection */
322 #define	NSMBFL_OPEN		0x0001
323 #define	NSMBFL_IOD		0x0002
324 #define	NSMBFL_IOCTL		0x0004
325 	int		sd_smbfid;	/* library read/write */
326 	zoneid_t	zoneid;		/* Zone id */
327 } smb_dev_t;
328 
329 extern const uint32_t nsmb_version;
330 
331 /*
332  * smb_dev.c
333  */
334 int  smb_dev2share(int fd, struct smb_share **sspp);
335 
336 
337 /*
338  * smb_usr.c
339  */
340 int smb_usr_ioctl(smb_dev_t *, int, intptr_t, int, cred_t *);
341 
342 int smb_usr_get_flags2(smb_dev_t *sdp, intptr_t arg, int flags);
343 int smb_usr_get_ssnkey(smb_dev_t *sdp, intptr_t arg, int flags);
344 int smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags);
345 
346 int smb_usr_simplerq(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
347 int smb_usr_t2request(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
348 
349 int smb_usr_closefh(smb_dev_t *, cred_t *);
350 int smb_usr_rw(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr);
351 int smb_usr_ntcreate(smb_dev_t *, intptr_t, int, cred_t *);
352 int smb_usr_printjob(smb_dev_t *, intptr_t, int, cred_t *);
353 
354 int smb_usr_get_ssn(smb_dev_t *, int, intptr_t, int, cred_t *);
355 int smb_usr_drop_ssn(smb_dev_t *sdp, int cmd);
356 
357 int smb_usr_get_tree(smb_dev_t *, int, intptr_t, int, cred_t *);
358 int smb_usr_drop_tree(smb_dev_t *sdp, int cmd);
359 
360 int smb_usr_iod_work(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr);
361 int smb_usr_iod_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags,
362     cred_t *cr);
363 
364 int smb_pkey_ioctl(int, intptr_t, int, cred_t *);
365 
366 
367 /*
368  * IOD functions
369  */
370 int  smb_iod_create(smb_vc_t *vcp);
371 int  smb_iod_destroy(smb_vc_t *vcp);
372 void smb_iod_disconnect(smb_vc_t *vcp);
373 int  smb_iod_addrq(struct smb_rq *rqp);
374 int  smb_iod_multirq(struct smb_rq *rqp);
375 int  smb_iod_waitrq(struct smb_rq *rqp);
376 void smb_iod_removerq(struct smb_rq *rqp);
377 int  smb_iod_sendrecv(struct smb_rq *, int);
378 void smb_iod_shutdown_share(smb_share_t *ssp);
379 
380 void smb_iod_sendall(smb_vc_t *);
381 int smb_iod_recvall(smb_vc_t *, boolean_t);
382 
383 int nsmb_iod_connect(smb_vc_t *vcp);
384 int nsmb_iod_negotiate(smb_vc_t *vcp, cred_t *cr);
385 int nsmb_iod_ssnsetup(smb_vc_t *vcp, cred_t *cr);
386 int smb_iod_vc_work(smb_vc_t *, int, cred_t *);
387 int smb_iod_vc_idle(smb_vc_t *);
388 int smb_iod_vc_rcfail(smb_vc_t *);
389 int smb_iod_reconnect(smb_vc_t *);
390 
391 /*
392  * Session level functions
393  */
394 int  smb_sm_init(void);
395 int  smb_sm_idle(void);
396 void smb_sm_done(void);
397 
398 /*
399  * VC level functions
400  */
401 void smb_vc_hold(smb_vc_t *vcp);
402 void smb_vc_rele(smb_vc_t *vcp);
403 void smb_vc_kill(smb_vc_t *vcp);
404 
405 int smb_vc_findcreate(smbioc_ossn_t *, smb_cred_t *, smb_vc_t **);
406 int smb_vc_create(smbioc_ossn_t *ossn, smb_cred_t *scred, smb_vc_t **vcpp);
407 
408 const char *smb_vc_getpass(smb_vc_t *vcp);
409 uint16_t smb_vc_nextmid(smb_vc_t *vcp);
410 void *smb_vc_getipaddr(smb_vc_t *vcp, int *ipvers);
411 
412 typedef void (*walk_share_func_t)(smb_share_t *);
413 void smb_vc_walkshares(struct smb_vc *,	walk_share_func_t);
414 
415 /*
416  * share level functions
417  */
418 
419 int smb_share_findcreate(smbioc_tcon_t *, smb_vc_t *,
420 	smb_share_t **, smb_cred_t *);
421 
422 void smb_share_hold(smb_share_t *ssp);
423 void smb_share_rele(smb_share_t *ssp);
424 void smb_share_kill(smb_share_t *ssp);
425 
426 void smb_share_invalidate(smb_share_t *ssp);
427 int  smb_share_tcon(smb_share_t *, smb_cred_t *);
428 
429 #endif /* _SMB_CONN_H */
430