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 2008 Sun Microsystems, Inc.  All rights reserved.
37  * Use is subject to license terms.
38  */
39 
40 #ifndef _SMB_CONN_H
41 #define	_SMB_CONN_H
42 
43 #pragma ident	"%Z%%M%	%I%	%E% SMI"
44 
45 #include <sys/t_lock.h>
46 #include <sys/queue.h> /* for SLIST below */
47 #include <sys/uio.h>
48 #include <netsmb/smb_dev.h>
49 
50 #ifndef _KERNEL
51 #error "Not _KERNEL?"
52 #endif
53 
54 /*
55  * Credentials of user/process for processing in the connection procedures
56  */
57 typedef struct smb_cred {
58 	pid_t	vc_pid;
59 	cred_t *vc_ucred;
60 } smb_cred_t;
61 
62 /*
63  * Common object flags
64  */
65 #define	SMBO_GONE		0x1000000
66 
67 /*
68  * Bits in vc_flags (a.k.a. vc_co.co_flags)
69  * Many of these were duplicates of SMBVOPT_ flags
70  * and we now keep those too instead of merging
71  * them into vc_flags.
72  */
73 
74 #define	SMBV_LONGNAMES		0x0004	/* conn configured to use long names */
75 #define	SMBV_ENCRYPT		0x0008	/* server demands encrypted password */
76 #define	SMBV_WIN95		0x0010	/* used to apply bugfixes for this OS */
77 #define	SMBV_NT4		0x0020	/* used when NT4 issues invalid resp */
78 #define	SMBV_RECONNECTING	0x0040	/* conn in process of reconnection */
79 /*				0x0200	   unused - was SMBV_FAILED */
80 #define	SMBV_UNICODE		0x0400	/* conn configured to use Unicode */
81 #define	SMBV_EXT_SEC		0x0800	/* conn to use extended security */
82 
83 /*
84  * Note: the common "obj" level uses this GONE flag by
85  * the name SMBO_GONE.  Keep this alias as a reminder.
86  */
87 #define	SMBV_GONE SMBO_GONE
88 
89 /*
90  * bits in smb_share ss_flags (a.k.a. ss_co.co_flags)
91  */
92 #define	SMBS_RECONNECTING	0x0002
93 #define	SMBS_CONNECTED		0x0004
94 #define	SMBS_TCON_WAIT		0x0008
95 #define	SMBS_1980		0x0010
96 /*
97  * ^ This partition can't handle dates before 1980. It's probably a FAT
98  * partition but could be some other ancient FS type
99  */
100 #define	SMBS_RESUMEKEYS		0x0010	/* must use resume keys */
101 /*
102  * Note: the common "obj" level uses this GONE flag by
103  * the name SMBO_GONE.  Keep this alias as a reminder.
104  */
105 #define	SMBS_GONE SMBO_GONE
106 
107 /*
108  * Negotiated protocol parameters
109  */
110 struct smb_sopt {
111 	int		sv_proto;
112 	int16_t		sv_tz;		/* offset in min relative to UTC */
113 	uint32_t	sv_maxtx;	/* maximum transmit buf size */
114 	uchar_t		sv_sm;		/* security mode */
115 	uint16_t	sv_maxmux;	/* max number of outstanding rq's */
116 	uint16_t 	sv_maxvcs;	/* max number of VCs */
117 	uint16_t	sv_rawmode;
118 	uint32_t	sv_maxraw;	/* maximum raw-buffer size */
119 	uint32_t	sv_skey;	/* session key */
120 	uint32_t	sv_caps;	/* capabilites SMB_CAP_ */
121 };
122 typedef struct smb_sopt smb_sopt_t;
123 
124 /*
125  * network IO daemon states
126  * really connection states.
127  */
128 enum smbiod_state {
129 	SMBIOD_ST_NOTCONN,	/* no connect request was made */
130 	SMBIOD_ST_RECONNECT,	/* a [re]connect attempt is in progress */
131 	SMBIOD_ST_TRANACTIVE,	/* transport level is up */
132 	SMBIOD_ST_NEGOACTIVE,	/* completed negotiation */
133 	SMBIOD_ST_SSNSETUP,	/* started (a) session setup */
134 	SMBIOD_ST_VCACTIVE,	/* session established */
135 	SMBIOD_ST_DEAD		/* connection broken, transport is down */
136 };
137 
138 
139 /*
140  * Info structures
141  */
142 #define	SMB_INFO_NONE		0
143 #define	SMB_INFO_VC		2
144 #define	SMB_INFO_SHARE		3
145 
146 struct smb_vc_info {
147 	int		itype;
148 	int		usecount;
149 	uid_t		uid;		/* user id of connection */
150 	gid_t		gid;		/* group of connection */
151 	mode_t		mode;		/* access mode */
152 	int		flags;
153 	enum smbiod_state iodstate;
154 	struct smb_sopt	sopt;
155 	char		srvname[SMB_MAXSRVNAMELEN+1];
156 	char		vcname[128];
157 };
158 typedef struct smb_vc_info smb_vc_info_t;
159 
160 struct smb_share_info {
161 	int		itype;
162 	int		usecount;
163 	ushort_t		tid;		/* TID */
164 	int		type;		/* share type */
165 	uid_t		uid;		/* user id of connection */
166 	gid_t		gid;		/* group of connection */
167 	mode_t		mode;		/* access mode */
168 	int		flags;
169 	char		sname[128];
170 };
171 typedef struct smb_share_info smb_share_info_t;
172 
173 struct smb_rq;
174 /* This declares struct smb_rqhead */
175 TAILQ_HEAD(smb_rqhead, smb_rq);
176 
177 #define	SMB_NBTIMO	15
178 #define	SMB_DEFRQTIMO	30	/* 30 for oplock revoke/writeback */
179 #define	SMBWRTTIMO	60
180 #define	SMBSSNSETUPTIMO	60
181 #define	SMBNOREPLYWAIT (0)
182 
183 #define	SMB_DIALECT(vcp)	((vcp)->vc_sopt.sv_proto)
184 
185 /*
186  * Connection object
187  */
188 
189 #define	SMB_CO_LOCK(cp)		mutex_enter(&(cp)->co_lock)
190 #define	SMB_CO_UNLOCK(cp)	mutex_exit(&(cp)->co_lock)
191 
192 /*
193  * Common part of smb_vc, smb_share
194  * Locking: co_lock protects most
195  * fields in this struct, except
196  * as noted below:
197  */
198 struct smb_connobj {
199 	kmutex_t		co_lock;
200 	int			co_level;	/* SMBL_ */
201 	int			co_flags;
202 	int			co_usecount;
203 
204 	/* Note: must lock co_parent before child. */
205 	struct smb_connobj	*co_parent;
206 
207 	/* this.co_lock protects the co_children list */
208 	SLIST_HEAD(, smb_connobj) co_children;
209 
210 	/*
211 	 * Linkage in parent's list of children.
212 	 * Must hold parent.co_lock to traverse.
213 	 */
214 	SLIST_ENTRY(smb_connobj) co_next;
215 
216 	/* These two are set only at creation. */
217 	void (*co_gone)(struct smb_connobj *);
218 	void (*co_free)(struct smb_connobj *);
219 };
220 typedef struct smb_connobj smb_connobj_t;
221 
222 /*
223  * Virtual Circuit (session) to a server.
224  * This is the most (over)complicated part of SMB protocol.
225  * For the user security level (usl), each session with different remote
226  * user name has its own VC.
227  * It is unclear however, should share security level (ssl) allow additional
228  * VCs, because user name is not used and can be the same. On other hand,
229  * multiple VCs allows us to create separate sessions to server on a per
230  * user basis.
231  */
232 
233 typedef struct smb_vc {
234 	struct smb_connobj vc_co;
235 	enum smbiod_state vc_state;
236 	kcondvar_t vc_statechg;
237 	ksema_t	vc_sendlock;
238 
239 	zoneid_t	vc_zoneid;
240 	char		*vc_srvname;
241 	struct sockaddr *vc_paddr;	/* server addr */
242 	struct sockaddr *vc_laddr;	/* local addr, if any */
243 	char		*vc_domain;	/* domain that defines username */
244 	char		*vc_username;
245 	char		*vc_pass;	/* password for usl case */
246 	uchar_t		vc_lmhash[SMB_PWH_MAX];
247 	uchar_t		vc_nthash[SMB_PWH_MAX];
248 
249 	uint_t		vc_timo;	/* default request timeout */
250 	int		vc_maxvcs;	/* maximum number of VC per conn */
251 
252 	void		*vc_tolower;	/* local charset */
253 	void		*vc_toupper;	/* local charset */
254 	void		*vc_toserver;	/* local charset to server one */
255 	void		*vc_tolocal;	/* server charset to local one */
256 	int		vc_number;	/* number of this VC from client side */
257 	int		vc_genid;	/* "generation ID" of this VC */
258 	uid_t		vc_uid;		/* user id of connection */
259 	gid_t		vc_grp;		/* group of connection */
260 	mode_t		vc_mode;	/* access mode */
261 	uint16_t	vc_smbuid;	/* auth. session ID from server */
262 
263 	uint8_t		vc_hflags;	/* or'ed with flags in the smb header */
264 	uint16_t	vc_hflags2;	/* or'ed with flags in the smb header */
265 	void		*vc_tdata;	/* transport control block */
266 	struct smb_tran_desc *vc_tdesc;
267 	int		vc_chlen;	/* actual challenge length */
268 	uchar_t 	vc_challenge[SMB_MAXCHALLENGELEN];
269 	uint16_t		vc_mid;		/* multiplex id */
270 	int		vc_vopt;	/* local options SMBVOPT_ */
271 	struct smb_sopt	vc_sopt;	/* server options */
272 	struct smb_cred	vc_scred;	/* used in reconnect procedure */
273 	int		vc_txmax;	/* max tx/rx packet size */
274 	int		vc_rxmax;	/* max readx data size */
275 	int		vc_wxmax;	/* max writex data size */
276 
277 	/* Authentication tokens */
278 	size_t		vc_intoklen;
279 	caddr_t		vc_intok;
280 	size_t		vc_outtoklen;
281 	caddr_t		vc_outtok;
282 	size_t		vc_negtoklen;
283 	caddr_t		vc_negtok;
284 
285 	/*
286 	 * These members used to be in struct smbiod,
287 	 * which has been eliminated.
288 	 */
289 	krwlock_t	iod_rqlock;	/* iod_rqlist */
290 	struct smb_rqhead	iod_rqlist;	/* list of outstanding reqs */
291 	struct _kthread 	*iod_thr;	/* the IOD (reader) thread */
292 	kcondvar_t		iod_exit; 	/* IOD thread termination */
293 	int			iod_flags;	/* see SMBIOD_* below */
294 	int			iod_newrq;	/* send needed (iod_rqlock) */
295 	int			iod_muxfull;	/* maxmux limit reached */
296 	uint_t		iod_rqwaiting;	/* count of waiting requests */
297 } smb_vc_t;
298 
299 #define	vc_lock		vc_co.co_lock
300 #define	vc_flags	vc_co.co_flags
301 #define	vc_maxmux	vc_sopt.sv_maxmux
302 
303 #define	SMB_VC_LOCK(vcp)	mutex_enter(&(vcp)->vc_lock)
304 #define	SMB_VC_UNLOCK(vcp)	mutex_exit(&(vcp)->vc_lock)
305 
306 #define	SMB_UNICODE_STRINGS(vcp)	((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE)
307 
308 /* Bits in iod_flags */
309 #define	SMBIOD_RUNNING		0x0001
310 #define	SMBIOD_SHUTDOWN		0x0002
311 
312 /*
313  * smb_share structure describes connection to the given SMB share (tree).
314  * Connection to share is always built on top of the VC.
315  */
316 
317 typedef struct smb_share {
318 	struct smb_connobj ss_co;
319 	kcondvar_t	ss_conn_done;	/* wait for reconnect */
320 	int		ss_conn_waiters;
321 	char		*ss_name;
322 	char		*ss_pass;	/* share password, can be null */
323 	char		*ss_fsname;
324 	void		*ss_mount;	/* used for smb up/down */
325 	uint16_t	ss_tid;		/* TID */
326 	int		ss_type;	/* share type */
327 	mode_t		ss_mode;	/* access mode */
328 	int		ss_vcgenid;	/* check VC generation ID */
329 	uint32_t	ss_maxfilenamelen;
330 	int		ss_sopt;	/* local options SMBSOPT_ */
331 } smb_share_t;
332 
333 #define	ss_lock		ss_co.co_lock
334 #define	ss_flags	ss_co.co_flags
335 
336 #define	SMB_SS_LOCK(ssp)	mutex_enter(&(ssp)->ss_lock)
337 #define	SMB_SS_UNLOCK(ssp)	mutex_exit(&(ssp)->ss_lock)
338 
339 #define	CPTOVC(cp)	((struct smb_vc *)(cp))
340 #define	VCTOCP(vcp)	(&(vcp)->vc_co)
341 
342 #define	CPTOSS(cp)	((struct smb_share *)(cp))
343 #define	SSTOVC(ssp)	CPTOVC(((ssp)->ss_co.co_parent))
344 #define	SSTOCP(ssp)	(&(ssp)->ss_co)
345 
346 /*
347  * This is used internally to pass all the info about
348  * some VC that an ioctl caller is looking for.
349  */
350 struct smb_vcspec {
351 	char		*srvname;
352 	struct sockaddr *sap;
353 	struct sockaddr *lap;
354 	int		optflags;
355 	char		*domain;
356 	char		*username;
357 	char		*pass;
358 	uid_t		owner;
359 	gid_t		group;
360 	mode_t		mode;
361 	mode_t		rights;
362 	char		*localcs;
363 	char		*servercs;
364 	size_t		toklen;
365 	caddr_t		tok;
366 };
367 typedef struct smb_vcspec smb_vcspec_t;
368 
369 /*
370  * This is used internally to pass all the info about
371  * some share that an ioctl caller is looking for.
372  */
373 struct smb_sharespec {
374 	char		*name;
375 	char		*pass;
376 	mode_t		mode;
377 	mode_t		rights;
378 	uid_t		owner;
379 	gid_t		group;
380 	int		stype;
381 	int		optflags;
382 };
383 typedef struct smb_sharespec smb_sharespec_t;
384 
385 
386 /*
387  * Call-back operations vector, so the netsmb module
388  * can notify smbfs about events affecting mounts.
389  * Installed in netsmb after smbfs loads.
390  */
391 /* #define NEED_SMBFS_CALLBACKS 1 */
392 #ifdef NEED_SMBFS_CALLBACKS
393 typedef struct smb_fscb {
394 	void (*fscb_dead)(smb_share_t *);
395 	void (*fscb_down)(smb_share_t *);
396 	void (*fscb_up)(smb_share_t *);
397 } smb_fscb_t;
398 /* Install the above vector, or pass NULL to clear it. */
399 int smb_fscb_set(smb_fscb_t *);
400 #endif /* NEED_SMBFS_CALLBACKS */
401 
402 /*
403  * IOD functions
404  */
405 int  smb_iod_create(struct smb_vc *vcp);
406 int  smb_iod_destroy(struct smb_vc *vcp);
407 int  smb_iod_connect(struct smb_vc *vcp);
408 int  smb_iod_disconnect(struct smb_vc *vcp);
409 int  smb_iod_addrq(struct smb_rq *rqp);
410 int  smb_iod_multirq(struct smb_rq *rqp);
411 int  smb_iod_waitrq(struct smb_rq *rqp);
412 int  smb_iod_removerq(struct smb_rq *rqp);
413 void smb_iod_shutdown_share(struct smb_share *ssp);
414 void smb_iod_notify_down(struct smb_vc *vcp);
415 void smb_iod_notify_up(struct smb_vc *vcp);
416 
417 /*
418  * Session level functions
419  */
420 int  smb_sm_init(void);
421 int  smb_sm_idle(void);
422 void smb_sm_done(void);
423 
424 int  smb_sm_findvc(struct smb_vcspec *vcspec,
425 	struct smb_cred *scred,	struct smb_vc **vcpp);
426 int  smb_sm_negotiate(struct smb_vcspec *vcspec,
427 	struct smb_cred *scred,	struct smb_vc **vcpp);
428 int  smb_sm_ssnsetup(struct smb_vcspec *vcspec,
429 	struct smb_cred *scred,	struct smb_vc *vcp);
430 int  smb_sm_tcon(struct smb_sharespec *shspec, struct smb_cred *scred,
431 	struct smb_vc *vcp, struct smb_share **sspp);
432 
433 /*
434  * VC level functions
435  */
436 int smb_vc_setup(struct smb_vcspec *vcspec, struct smb_cred *scred,
437 	struct smb_vc *vcp, int is_ss);
438 int  smb_vc_create(struct smb_vcspec *vcspec,
439 	struct smb_cred *scred, struct smb_vc **vcpp);
440 int  smb_vc_negotiate(struct smb_vc *vcp, struct smb_cred *scred);
441 int  smb_vc_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred);
442 void smb_vc_hold(struct smb_vc *vcp);
443 void smb_vc_rele(struct smb_vc *vcp);
444 void smb_vc_kill(struct smb_vc *vcp);
445 int  smb_vc_lookupshare(struct smb_vc *vcp, struct smb_sharespec *shspec,
446 	struct smb_cred *scred, struct smb_share **sspp);
447 const char *smb_vc_getpass(struct smb_vc *vcp);
448 uint16_t smb_vc_nextmid(struct smb_vc *vcp);
449 void *smb_vc_getipaddr(struct smb_vc *vcp, int *ipvers);
450 
451 /*
452  * share level functions
453  */
454 int  smb_share_create(struct smb_vc *vcp, struct smb_sharespec *shspec,
455 	struct smb_cred *scred, struct smb_share **sspp);
456 
457 void smb_share_hold(struct smb_share *ssp);
458 void smb_share_rele(struct smb_share *ssp);
459 void smb_share_kill(struct smb_share *ssp);
460 
461 void smb_share_invalidate(struct smb_share *ssp);
462 int  smb_share_tcon(struct smb_share *ssp);
463 int  smb_share_valid(struct smb_share *ssp);
464 const char *smb_share_getpass(struct smb_share *ssp);
465 int  smb_share_count(void);
466 
467 /*
468  * SMB protocol level functions
469  */
470 int  smb_smb_negotiate(struct smb_vc *vcp, struct smb_cred *scred);
471 int  smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred);
472 int  smb_smb_ssnclose(struct smb_vc *vcp, struct smb_cred *scred);
473 int  smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred);
474 int  smb_smb_treedisconnect(struct smb_share *ssp, struct smb_cred *scred);
475 int  smb_smb_echo(struct smb_vc *vcp, struct smb_cred *scred, int timo);
476 #ifdef APPLE
477 int  smb_smb_checkdir(struct smb_share *ssp, void *dnp,
478 	char *name, int nmlen, struct smb_cred *scred);
479 #endif
480 int smb_rwuio(struct smb_share *ssp, uint16_t fid, uio_rw_t rw,
481 	uio_t *uiop, struct smb_cred *scred, int timo);
482 
483 #endif /* _SMB_CONN_H */
484