Commit | Line | Data |
---|---|---|
984263bc MD |
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 | * $FreeBSD: src/sys/netsmb/smb_conn.h,v 1.1.2.3 2002/04/23 03:45:01 bp Exp $ | |
33 | */ | |
83a41782 SW |
34 | |
35 | #ifndef _NETPROTO_SMB_SMB_CONN_H_ | |
36 | #define _NETPROTO_SMB_SMB_CONN_H_ | |
37 | ||
49c0db25 | 38 | #include <sys/types.h> |
984263bc MD |
39 | #ifndef _NETINET_IN_H_ |
40 | #include <netinet/in.h> | |
41 | #endif | |
42 | ||
43 | /* | |
44 | * Two levels of connection hierarchy | |
45 | */ | |
46 | #define SMBL_SM 0 | |
47 | #define SMBL_VC 1 | |
48 | #define SMBL_SHARE 2 | |
49 | #define SMBL_NUM 3 | |
50 | #define SMBL_NONE (-1) | |
51 | ||
52 | #define SMB_CS_NONE 0x0000 | |
53 | #define SMB_CS_UPPER 0x0001 /* convert passed string to upper case */ | |
54 | #define SMB_CS_LOWER 0x0002 /* convert passed string to lower case */ | |
55 | ||
56 | /* | |
57 | * Common object flags | |
58 | */ | |
59 | #define SMBO_GONE 0x1000000 | |
60 | ||
61 | /* | |
62 | * access modes | |
63 | */ | |
64 | #define SMBM_READ 0400 /* read conn attrs.(like list shares) */ | |
65 | #define SMBM_WRITE 0200 /* modify conn attrs */ | |
66 | #define SMBM_EXEC 0100 /* can send SMB requests */ | |
67 | #define SMBM_READGRP 0040 | |
68 | #define SMBM_WRITEGRP 0020 | |
69 | #define SMBM_EXECGRP 0010 | |
70 | #define SMBM_READOTH 0004 | |
71 | #define SMBM_WRITEOTH 0002 | |
72 | #define SMBM_EXECOTH 0001 | |
73 | #define SMBM_MASK 0777 | |
74 | #define SMBM_EXACT 010000 /* check for specified mode exactly */ | |
75 | #define SMBM_ALL (SMBM_READ | SMBM_WRITE | SMBM_EXEC) | |
76 | #define SMBM_DEFAULT (SMBM_READ | SMBM_WRITE | SMBM_EXEC) | |
77 | #define SMBM_ANY_OWNER ((uid_t)-1) | |
78 | #define SMBM_ANY_GROUP ((gid_t)-1) | |
79 | ||
80 | /* | |
81 | * VC flags | |
82 | */ | |
83 | #define SMBV_PERMANENT 0x0002 | |
84 | #define SMBV_LONGNAMES 0x0004 /* connection is configured to use long names */ | |
85 | #define SMBV_ENCRYPT 0x0008 /* server asked for encrypted password */ | |
86 | #define SMBV_WIN95 0x0010 /* used to apply bugfixes for this OS */ | |
87 | #define SMBV_PRIVATE 0x0020 /* connection can be used only by creator */ | |
88 | #define SMBV_RECONNECTING 0x0040 /* conn is in the process of reconnection */ | |
89 | #define SMBV_SINGLESHARE 0x0080 /* only one share connecting should be allowed */ | |
90 | #define SMBV_CREATE 0x0100 /* lookup for create operation */ | |
91 | /*#define SMBV_FAILED 0x0200*/ /* last reconnect attempt has failed */ | |
92 | #define SMBV_UNICODE 0x0400 /* connection is configured to use Unicode */ | |
93 | ||
94 | ||
95 | /* | |
96 | * smb_share flags | |
97 | */ | |
98 | #define SMBS_PERMANENT 0x0001 | |
99 | #define SMBS_RECONNECTING 0x0002 | |
100 | #define SMBS_CONNECTED 0x0004 | |
101 | ||
102 | /* | |
103 | * share types | |
104 | */ | |
105 | #define SMB_ST_DISK 0x0 /* A: */ | |
106 | #define SMB_ST_PRINTER 0x1 /* LPT: */ | |
107 | #define SMB_ST_PIPE 0x2 /* IPC */ | |
108 | #define SMB_ST_COMM 0x3 /* COMM */ | |
109 | #define SMB_ST_ANY 0x4 | |
110 | #define SMB_ST_MAX 0x4 | |
111 | #define SMB_ST_NONE 0xff /* not a part of protocol */ | |
112 | ||
113 | /* | |
114 | * Negotiated protocol parameters | |
115 | */ | |
116 | struct smb_sopt { | |
117 | int sv_proto; | |
118 | int16_t sv_tz; /* offset in min relative to UTC */ | |
119 | u_int32_t sv_maxtx; /* maximum transmit buf size */ | |
120 | u_char sv_sm; /* security mode */ | |
121 | u_int16_t sv_maxmux; /* max number of outstanding rq's */ | |
122 | u_int16_t sv_maxvcs; /* max number of VCs */ | |
123 | u_int16_t sv_rawmode; | |
124 | u_int32_t sv_maxraw; /* maximum raw-buffer size */ | |
125 | u_int32_t sv_skey; /* session key */ | |
126 | u_int32_t sv_caps; /* capabilities SMB_CAP_ */ | |
127 | }; | |
128 | ||
129 | /* | |
130 | * network IO daemon states | |
131 | */ | |
132 | enum smbiod_state { | |
133 | SMBIOD_ST_NOTCONN, /* no connect request was made */ | |
134 | SMBIOD_ST_RECONNECT, /* a [re]connect attempt is in progress */ | |
135 | SMBIOD_ST_TRANACTIVE, /* transport level is up */ | |
136 | SMBIOD_ST_VCACTIVE, /* session established */ | |
137 | SMBIOD_ST_DEAD /* connection broken, transport is down */ | |
138 | }; | |
139 | ||
140 | ||
141 | /* | |
142 | * Info structures | |
143 | */ | |
144 | #define SMB_INFO_NONE 0 | |
145 | #define SMB_INFO_VC 2 | |
146 | #define SMB_INFO_SHARE 3 | |
147 | ||
148 | struct smb_vc_info { | |
149 | int itype; | |
150 | int usecount; | |
151 | uid_t uid; /* user id of connection */ | |
152 | gid_t gid; /* group of connection */ | |
153 | mode_t mode; /* access mode */ | |
154 | int flags; | |
155 | enum smbiod_state iodstate; | |
156 | struct smb_sopt sopt; | |
157 | char srvname[SMB_MAXSRVNAMELEN]; | |
158 | char vcname[128]; | |
159 | }; | |
160 | ||
161 | struct smb_share_info { | |
162 | int itype; | |
163 | int usecount; | |
164 | u_short 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 | ||
173 | #ifdef _KERNEL | |
174 | ||
175 | #include <sys/lock.h> | |
1f2de5d4 | 176 | #include "smb_subr.h" |
984263bc MD |
177 | |
178 | #define CONNADDREQ(a1,a2) ((a1)->sa_len == (a2)->sa_len && \ | |
179 | bcmp(a1, a2, (a1)->sa_len) == 0) | |
180 | ||
181 | struct smb_vc; | |
182 | struct smb_share; | |
183 | struct smb_cred; | |
184 | struct smb_rq; | |
185 | struct mbdata; | |
186 | struct smbioc_oshare; | |
187 | struct smbioc_ossn; | |
188 | struct uio; | |
189 | ||
190 | TAILQ_HEAD(smb_rqhead, smb_rq); | |
191 | ||
192 | #define SMB_DEFRQTIMO 5 | |
193 | ||
194 | #define SMB_DIALECT(vcp) ((vcp)->vc_sopt.sv_proto) | |
195 | ||
196 | struct smb_tran_desc; | |
197 | ||
198 | /* | |
199 | * Connection object | |
200 | */ | |
201 | struct smb_connobj; | |
202 | ||
203 | typedef void smb_co_gone_t (struct smb_connobj *cp, struct smb_cred *scred); | |
204 | typedef void smb_co_free_t (struct smb_connobj *cp); | |
205 | ||
8886b1fc MD |
206 | #define SMB_CO_LOCK(cp) smb_sl_lock(&(cp)->co_interlock) |
207 | #define SMB_CO_UNLOCK(cp) smb_sl_unlock(&(cp)->co_interlock) | |
208 | #define SMB_CO_INTERLOCK(cp) (&(cp)->co_interlock) | |
984263bc MD |
209 | |
210 | struct smb_connobj { | |
211 | int co_level; /* SMBL_ */ | |
212 | int co_flags; | |
213 | struct lock co_lock; | |
214 | struct smb_slock co_interlock; | |
215 | int co_usecount; | |
216 | struct smb_connobj * co_parent; | |
217 | SLIST_HEAD(,smb_connobj)co_children; | |
218 | SLIST_ENTRY(smb_connobj)co_next; | |
219 | smb_co_gone_t * co_gone; | |
220 | smb_co_free_t * co_free; | |
221 | }; | |
222 | ||
223 | #define SMBCO_FOREACH(var, cp) SLIST_FOREACH((var), &(cp)->co_children, co_next) | |
224 | ||
225 | /* | |
226 | * Virtual Circuit (session) to a server. | |
227 | * This is the most (over)complicated part of SMB protocol. | |
228 | * For the user security level (usl), each session with different remote | |
229 | * user name has its own VC. | |
230 | * It is unclear however, should share security level (ssl) allow additional | |
231 | * VCs, because user name is not used and can be the same. On other hand, | |
232 | * multiple VCs allows us to create separate sessions to server on a per | |
233 | * user basis. | |
234 | */ | |
235 | ||
236 | /* | |
237 | * This lock protects vc_flags | |
238 | */ | |
8886b1fc MD |
239 | #define SMBC_ST_LOCK(vcp) smb_sl_lock(&(vcp)->vc_stlock) |
240 | #define SMBC_ST_UNLOCK(vcp) smb_sl_unlock(&(vcp)->vc_stlock) | |
984263bc MD |
241 | |
242 | ||
243 | struct smb_vc { | |
244 | struct smb_connobj obj; | |
245 | char * vc_srvname; | |
246 | struct sockaddr*vc_paddr; /* server addr */ | |
247 | struct sockaddr*vc_laddr; /* local addr, if any */ | |
248 | char * vc_username; | |
249 | char * vc_pass; /* password for usl case */ | |
250 | char * vc_domain; /* workgroup/primary domain */ | |
251 | ||
252 | u_int vc_timo; /* default request timeout */ | |
253 | int vc_maxvcs; /* maximum number of VC per connection */ | |
254 | ||
255 | void * vc_tolower; /* local charset */ | |
256 | void * vc_toupper; /* local charset */ | |
257 | void * vc_toserver; /* local charset to server one */ | |
258 | void * vc_tolocal; /* server charset to local one */ | |
259 | int vc_number; /* number of this VC from the client side */ | |
260 | int vc_genid; | |
261 | uid_t vc_uid; /* user id of connection */ | |
262 | gid_t vc_grp; /* group of connection */ | |
263 | mode_t vc_mode; /* access mode */ | |
264 | struct tnode * vc_tnode; /* backing object */ | |
265 | u_short vc_smbuid; /* unique vc id assigned by server */ | |
266 | ||
267 | u_char vc_hflags; /* or'ed with flags in the smb header */ | |
268 | u_short 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 | u_char vc_ch[SMB_MAXCHALLENGELEN]; | |
273 | u_short vc_mid; /* multiplex id */ | |
274 | struct smb_sopt vc_sopt; /* server options */ | |
275 | int vc_txmax; /* max tx/rx packet size */ | |
276 | struct smbiod * vc_iod; | |
277 | struct smb_slock vc_stlock; | |
e0bd597d MD |
278 | u_int32_t vc_seqno; /* my next sequence number */ |
279 | u_int8_t *vc_mackey; /* MAC key */ | |
280 | int vc_mackeylen; /* length of MAC key */ | |
984263bc MD |
281 | }; |
282 | ||
283 | #define vc_maxmux vc_sopt.sv_maxmux | |
284 | #define vc_flags obj.co_flags | |
285 | ||
286 | ||
287 | /* | |
288 | * smb_share structure describes connection to the given SMB share (tree). | |
289 | * Connection to share is always built on top of the VC. | |
290 | */ | |
291 | ||
292 | /* | |
293 | * This lock protects ss_flags | |
294 | */ | |
8886b1fc MD |
295 | #define SMBS_ST_LOCK(ssp) smb_sl_lock(&(ssp)->ss_stlock) |
296 | #define SMBS_ST_LOCKPTR(ssp) (&(ssp)->ss_stlock) | |
297 | #define SMBS_ST_INTERLOCK(ssp) (&(ssp)->ss_stlock) | |
298 | #define SMBS_ST_UNLOCK(ssp) smb_sl_unlock(&(ssp)->ss_stlock) | |
984263bc MD |
299 | |
300 | struct smb_share { | |
301 | struct smb_connobj obj; | |
302 | char * ss_name; | |
303 | u_short ss_tid; /* TID */ | |
304 | int ss_type; /* share type */ | |
305 | uid_t ss_uid; /* user id of connection */ | |
306 | gid_t ss_grp; /* group of connection */ | |
307 | mode_t ss_mode; /* access mode */ | |
308 | int ss_vcgenid; | |
309 | char * ss_pass; /* password to a share, can be null */ | |
310 | struct smb_slock ss_stlock; | |
311 | }; | |
312 | ||
313 | #define ss_flags obj.co_flags | |
314 | ||
315 | #define CPTOVC(cp) ((struct smb_vc*)(cp)) | |
316 | #define VCTOCP(vcp) (&(vcp)->obj) | |
317 | #define CPTOSS(cp) ((struct smb_share*)(cp)) | |
318 | #define SSTOVC(ssp) CPTOVC(((ssp)->obj.co_parent)) | |
319 | #define SSTOCP(ssp) (&(ssp)->obj) | |
320 | ||
321 | struct smb_vcspec { | |
322 | char * srvname; | |
323 | struct sockaddr*sap; | |
324 | struct sockaddr*lap; | |
325 | int flags; | |
326 | char * username; | |
327 | char * pass; | |
328 | char * domain; | |
329 | mode_t mode; | |
330 | mode_t rights; | |
331 | uid_t owner; | |
332 | gid_t group; | |
333 | char * localcs; | |
334 | char * servercs; | |
335 | struct smb_sharespec *shspec; | |
336 | struct smb_share *ssp; /* returned */ | |
337 | /* | |
338 | * The rest is an internal data | |
339 | */ | |
340 | struct smb_cred *scred; | |
341 | }; | |
342 | ||
343 | struct smb_sharespec { | |
344 | char * name; | |
345 | char * pass; | |
346 | mode_t mode; | |
347 | mode_t rights; | |
348 | uid_t owner; | |
349 | gid_t group; | |
350 | int stype; | |
351 | /* | |
352 | * The rest is an internal data | |
353 | */ | |
354 | struct smb_cred *scred; | |
355 | }; | |
356 | ||
357 | /* | |
358 | * Session level functions | |
359 | */ | |
360 | int smb_sm_init(void); | |
361 | int smb_sm_done(void); | |
362 | int smb_sm_lookup(struct smb_vcspec *vcspec, | |
363 | struct smb_sharespec *shspec, struct smb_cred *scred, | |
364 | struct smb_vc **vcpp); | |
365 | ||
984263bc MD |
366 | /* |
367 | * session level functions | |
368 | */ | |
369 | int smb_vc_create(struct smb_vcspec *vcspec, | |
370 | struct smb_cred *scred, struct smb_vc **vcpp); | |
371 | int smb_vc_connect(struct smb_vc *vcp, struct smb_cred *scred); | |
372 | int smb_vc_access(struct smb_vc *vcp, struct smb_cred *scred, mode_t mode); | |
373 | int smb_vc_get(struct smb_vc *vcp, int flags, struct smb_cred *scred); | |
374 | void smb_vc_put(struct smb_vc *vcp, struct smb_cred *scred); | |
fef8985e | 375 | void smb_vc_ref(struct smb_vc *vcp); |
984263bc | 376 | void smb_vc_rele(struct smb_vc *vcp, struct smb_cred *scred); |
fef8985e MD |
377 | int smb_vc_lock(struct smb_vc *vcp, int flags); |
378 | void smb_vc_unlock(struct smb_vc *vcp, int flags); | |
984263bc MD |
379 | int smb_vc_lookupshare(struct smb_vc *vcp, struct smb_sharespec *shspec, |
380 | struct smb_cred *scred, struct smb_share **sspp); | |
381 | const char * smb_vc_getpass(struct smb_vc *vcp); | |
382 | u_short smb_vc_nextmid(struct smb_vc *vcp); | |
383 | ||
384 | /* | |
385 | * share level functions | |
386 | */ | |
387 | int smb_share_create(struct smb_vc *vcp, struct smb_sharespec *shspec, | |
388 | struct smb_cred *scred, struct smb_share **sspp); | |
389 | int smb_share_access(struct smb_share *ssp, struct smb_cred *scred, mode_t mode); | |
fef8985e | 390 | void smb_share_ref(struct smb_share *ssp); |
984263bc MD |
391 | void smb_share_rele(struct smb_share *ssp, struct smb_cred *scred); |
392 | int smb_share_get(struct smb_share *ssp, int flags, struct smb_cred *scred); | |
393 | void smb_share_put(struct smb_share *ssp, struct smb_cred *scred); | |
fef8985e MD |
394 | int smb_share_lock(struct smb_share *ssp, int flags); |
395 | void smb_share_unlock(struct smb_share *ssp, int flags); | |
984263bc MD |
396 | void smb_share_invalidate(struct smb_share *ssp); |
397 | int smb_share_valid(struct smb_share *ssp); | |
398 | const char * smb_share_getpass(struct smb_share *ssp); | |
399 | ||
400 | /* | |
401 | * SMB protocol level functions | |
402 | */ | |
403 | int smb_smb_negotiate(struct smb_vc *vcp, struct smb_cred *scred); | |
404 | int smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred); | |
405 | int smb_smb_ssnclose(struct smb_vc *vcp, struct smb_cred *scred); | |
406 | int smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred); | |
407 | int smb_smb_treedisconnect(struct smb_share *ssp, struct smb_cred *scred); | |
408 | int smb_read(struct smb_share *ssp, u_int16_t fid, struct uio *uio, | |
409 | struct smb_cred *scred); | |
410 | int smb_write(struct smb_share *ssp, u_int16_t fid, struct uio *uio, | |
411 | struct smb_cred *scred); | |
412 | int smb_smb_echo(struct smb_vc *vcp, struct smb_cred *scred); | |
413 | ||
414 | /* | |
415 | * smbiod thread | |
416 | */ | |
417 | ||
418 | #define SMBIOD_EV_NEWRQ 0x0001 | |
419 | #define SMBIOD_EV_SHUTDOWN 0x0002 | |
420 | #define SMBIOD_EV_CONNECT 0x0003 | |
421 | #define SMBIOD_EV_DISCONNECT 0x0004 | |
422 | #define SMBIOD_EV_TREECONNECT 0x0005 | |
423 | #define SMBIOD_EV_MASK 0x00ff | |
424 | #define SMBIOD_EV_SYNC 0x0100 | |
425 | #define SMBIOD_EV_PROCESSING 0x0200 | |
426 | ||
427 | struct smbiod_event { | |
428 | int ev_type; | |
429 | int ev_error; | |
430 | void * ev_ident; | |
431 | STAILQ_ENTRY(smbiod_event) ev_link; | |
432 | }; | |
433 | ||
434 | #define SMBIOD_SHUTDOWN 0x0001 | |
435 | ||
436 | struct smbiod { | |
437 | int iod_id; | |
438 | int iod_flags; | |
439 | enum smbiod_state iod_state; | |
440 | int iod_muxcnt; /* number of active outstanding requests */ | |
441 | int iod_sleeptimo; | |
442 | struct smb_vc * iod_vc; | |
443 | struct smb_slock iod_rqlock; /* iod_rqlist, iod_muxwant */ | |
444 | struct smb_rqhead iod_rqlist; /* list of outstanding requests */ | |
445 | int iod_muxwant; | |
dadab5e9 | 446 | struct thread * iod_td; |
984263bc MD |
447 | struct smb_cred iod_scred; |
448 | struct smb_slock iod_evlock; /* iod_evlist */ | |
449 | STAILQ_HEAD(,smbiod_event) iod_evlist; | |
450 | struct timespec iod_lastrqsent; | |
451 | struct timespec iod_pingtimo; | |
452 | }; | |
453 | ||
454 | int smb_iod_init(void); | |
455 | int smb_iod_done(void); | |
456 | int smb_iod_create(struct smb_vc *vcp); | |
457 | int smb_iod_destroy(struct smbiod *iod); | |
458 | int smb_iod_request(struct smbiod *iod, int event, void *ident); | |
459 | int smb_iod_addrq(struct smb_rq *rqp); | |
460 | int smb_iod_waitrq(struct smb_rq *rqp); | |
461 | int smb_iod_removerq(struct smb_rq *rqp); | |
462 | ||
463 | #endif /* _KERNEL */ | |
83a41782 SW |
464 | |
465 | #endif /* !_NETPROTO_SMB_SMB_CONN_H_ */ |