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