1 | // SPDX-License-Identifier: LGPL-2.1 |
2 | /* |
3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2011 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * |
7 | */ |
8 | #include <linux/fs.h> |
9 | #include <linux/net.h> |
10 | #include <linux/string.h> |
11 | #include <linux/sched/mm.h> |
12 | #include <linux/sched/signal.h> |
13 | #include <linux/list.h> |
14 | #include <linux/wait.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/pagemap.h> |
17 | #include <linux/ctype.h> |
18 | #include <linux/utsname.h> |
19 | #include <linux/mempool.h> |
20 | #include <linux/delay.h> |
21 | #include <linux/completion.h> |
22 | #include <linux/kthread.h> |
23 | #include <linux/pagevec.h> |
24 | #include <linux/freezer.h> |
25 | #include <linux/namei.h> |
26 | #include <linux/uuid.h> |
27 | #include <linux/uaccess.h> |
28 | #include <asm/processor.h> |
29 | #include <linux/inet.h> |
30 | #include <linux/module.h> |
31 | #include <keys/user-type.h> |
32 | #include <net/ipv6.h> |
33 | #include <linux/parser.h> |
34 | #include <linux/bvec.h> |
35 | #include "cifspdu.h" |
36 | #include "cifsglob.h" |
37 | #include "cifsproto.h" |
38 | #include "cifs_unicode.h" |
39 | #include "cifs_debug.h" |
40 | #include "cifs_fs_sb.h" |
41 | #include "ntlmssp.h" |
42 | #include "nterr.h" |
43 | #include "rfc1002pdu.h" |
44 | #include "fscache.h" |
45 | #include "smb2proto.h" |
46 | #include "smbdirect.h" |
47 | #include "dns_resolve.h" |
48 | #ifdef CONFIG_CIFS_DFS_UPCALL |
49 | #include "dfs.h" |
50 | #include "dfs_cache.h" |
51 | #endif |
52 | #include "fs_context.h" |
53 | #include "cifs_swn.h" |
54 | |
55 | /* FIXME: should these be tunable? */ |
56 | #define TLINK_ERROR_EXPIRE (1 * HZ) |
57 | #define TLINK_IDLE_EXPIRE (600 * HZ) |
58 | |
59 | /* Drop the connection to not overload the server */ |
60 | #define MAX_STATUS_IO_TIMEOUT 5 |
61 | |
62 | static int ip_connect(struct TCP_Server_Info *server); |
63 | static int generic_ip_connect(struct TCP_Server_Info *server); |
64 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); |
65 | static void cifs_prune_tlinks(struct work_struct *work); |
66 | |
67 | /* |
68 | * Resolve hostname and set ip addr in tcp ses. Useful for hostnames that may |
69 | * get their ip addresses changed at some point. |
70 | * |
71 | * This should be called with server->srv_mutex held. |
72 | */ |
73 | static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server) |
74 | { |
75 | struct sockaddr_storage ss; |
76 | int rc; |
77 | |
78 | if (!server->hostname) |
79 | return -EINVAL; |
80 | |
81 | /* if server hostname isn't populated, there's nothing to do here */ |
82 | if (server->hostname[0] == '\0') |
83 | return 0; |
84 | |
85 | spin_lock(lock: &server->srv_lock); |
86 | ss = server->dstaddr; |
87 | spin_unlock(lock: &server->srv_lock); |
88 | |
89 | rc = dns_resolve_name(dom: server->dns_dom, name: server->hostname, |
90 | strlen(server->hostname), |
91 | ip_addr: (struct sockaddr *)&ss); |
92 | if (!rc) { |
93 | spin_lock(lock: &server->srv_lock); |
94 | memcpy(&server->dstaddr, &ss, sizeof(server->dstaddr)); |
95 | spin_unlock(lock: &server->srv_lock); |
96 | } |
97 | return rc; |
98 | } |
99 | |
100 | static void smb2_query_server_interfaces(struct work_struct *work) |
101 | { |
102 | int rc; |
103 | int xid; |
104 | struct cifs_tcon *tcon = container_of(work, |
105 | struct cifs_tcon, |
106 | query_interfaces.work); |
107 | struct TCP_Server_Info *server = tcon->ses->server; |
108 | |
109 | /* |
110 | * query server network interfaces, in case they change |
111 | */ |
112 | if (!server->ops->query_server_interfaces) |
113 | return; |
114 | |
115 | xid = get_xid(); |
116 | rc = server->ops->query_server_interfaces(xid, tcon, false); |
117 | free_xid(xid); |
118 | |
119 | if (rc) |
120 | cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n" , |
121 | __func__, rc); |
122 | |
123 | queue_delayed_work(wq: cifsiod_wq, dwork: &tcon->query_interfaces, |
124 | delay: (SMB_INTERFACE_POLL_INTERVAL * HZ)); |
125 | } |
126 | |
127 | /* |
128 | * Update the tcpStatus for the server. |
129 | * This is used to signal the cifsd thread to call cifs_reconnect |
130 | * ONLY cifsd thread should call cifs_reconnect. For any other |
131 | * thread, use this function |
132 | * |
133 | * @server: the tcp ses for which reconnect is needed |
134 | * @all_channels: if this needs to be done for all channels |
135 | */ |
136 | void |
137 | cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server, |
138 | bool all_channels) |
139 | { |
140 | struct TCP_Server_Info *pserver; |
141 | struct cifs_ses *ses; |
142 | int i; |
143 | |
144 | /* If server is a channel, select the primary channel */ |
145 | pserver = SERVER_IS_CHAN(server) ? server->primary_server : server; |
146 | |
147 | /* if we need to signal just this channel */ |
148 | if (!all_channels) { |
149 | spin_lock(lock: &server->srv_lock); |
150 | if (server->tcpStatus != CifsExiting) |
151 | server->tcpStatus = CifsNeedReconnect; |
152 | spin_unlock(lock: &server->srv_lock); |
153 | return; |
154 | } |
155 | |
156 | spin_lock(lock: &cifs_tcp_ses_lock); |
157 | list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { |
158 | if (cifs_ses_exiting(ses)) |
159 | continue; |
160 | spin_lock(lock: &ses->chan_lock); |
161 | for (i = 0; i < ses->chan_count; i++) { |
162 | if (!ses->chans[i].server) |
163 | continue; |
164 | |
165 | spin_lock(lock: &ses->chans[i].server->srv_lock); |
166 | if (ses->chans[i].server->tcpStatus != CifsExiting) |
167 | ses->chans[i].server->tcpStatus = CifsNeedReconnect; |
168 | spin_unlock(lock: &ses->chans[i].server->srv_lock); |
169 | } |
170 | spin_unlock(lock: &ses->chan_lock); |
171 | } |
172 | spin_unlock(lock: &cifs_tcp_ses_lock); |
173 | } |
174 | |
175 | /* |
176 | * Mark all sessions and tcons for reconnect. |
177 | * IMPORTANT: make sure that this gets called only from |
178 | * cifsd thread. For any other thread, use |
179 | * cifs_signal_cifsd_for_reconnect |
180 | * |
181 | * @server: the tcp ses for which reconnect is needed |
182 | * @server needs to be previously set to CifsNeedReconnect. |
183 | * @mark_smb_session: whether even sessions need to be marked |
184 | */ |
185 | void |
186 | cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, |
187 | bool mark_smb_session) |
188 | { |
189 | struct TCP_Server_Info *pserver; |
190 | struct cifs_ses *ses, *nses; |
191 | struct cifs_tcon *tcon; |
192 | |
193 | /* |
194 | * before reconnecting the tcp session, mark the smb session (uid) and the tid bad so they |
195 | * are not used until reconnected. |
196 | */ |
197 | cifs_dbg(FYI, "%s: marking necessary sessions and tcons for reconnect\n" , __func__); |
198 | |
199 | /* If server is a channel, select the primary channel */ |
200 | pserver = SERVER_IS_CHAN(server) ? server->primary_server : server; |
201 | |
202 | /* |
203 | * if the server has been marked for termination, there is a |
204 | * chance that the remaining channels all need reconnect. To be |
205 | * on the safer side, mark the session and trees for reconnect |
206 | * for this scenario. This might cause a few redundant session |
207 | * setup and tree connect requests, but it is better than not doing |
208 | * a tree connect when needed, and all following requests failing |
209 | */ |
210 | if (server->terminate) { |
211 | mark_smb_session = true; |
212 | server = pserver; |
213 | } |
214 | |
215 | spin_lock(lock: &cifs_tcp_ses_lock); |
216 | list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { |
217 | spin_lock(lock: &ses->ses_lock); |
218 | if (ses->ses_status == SES_EXITING) { |
219 | spin_unlock(lock: &ses->ses_lock); |
220 | continue; |
221 | } |
222 | spin_unlock(lock: &ses->ses_lock); |
223 | |
224 | spin_lock(lock: &ses->chan_lock); |
225 | if (cifs_ses_get_chan_index(ses, server) == |
226 | CIFS_INVAL_CHAN_INDEX) { |
227 | spin_unlock(lock: &ses->chan_lock); |
228 | continue; |
229 | } |
230 | |
231 | if (!cifs_chan_is_iface_active(ses, server)) { |
232 | spin_unlock(lock: &ses->chan_lock); |
233 | cifs_chan_update_iface(ses, server); |
234 | spin_lock(lock: &ses->chan_lock); |
235 | } |
236 | |
237 | if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) { |
238 | spin_unlock(lock: &ses->chan_lock); |
239 | continue; |
240 | } |
241 | |
242 | if (mark_smb_session) |
243 | CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses); |
244 | else |
245 | cifs_chan_set_need_reconnect(ses, server); |
246 | |
247 | cifs_dbg(FYI, "%s: channel connect bitmap: 0x%lx\n" , |
248 | __func__, ses->chans_need_reconnect); |
249 | |
250 | /* If all channels need reconnect, then tcon needs reconnect */ |
251 | if (!mark_smb_session && !CIFS_ALL_CHANS_NEED_RECONNECT(ses)) { |
252 | spin_unlock(lock: &ses->chan_lock); |
253 | continue; |
254 | } |
255 | spin_unlock(lock: &ses->chan_lock); |
256 | |
257 | spin_lock(lock: &ses->ses_lock); |
258 | ses->ses_status = SES_NEED_RECON; |
259 | spin_unlock(lock: &ses->ses_lock); |
260 | |
261 | list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { |
262 | tcon->need_reconnect = true; |
263 | spin_lock(lock: &tcon->tc_lock); |
264 | tcon->status = TID_NEED_RECON; |
265 | spin_unlock(lock: &tcon->tc_lock); |
266 | |
267 | cancel_delayed_work(dwork: &tcon->query_interfaces); |
268 | } |
269 | if (ses->tcon_ipc) { |
270 | ses->tcon_ipc->need_reconnect = true; |
271 | spin_lock(lock: &ses->tcon_ipc->tc_lock); |
272 | ses->tcon_ipc->status = TID_NEED_RECON; |
273 | spin_unlock(lock: &ses->tcon_ipc->tc_lock); |
274 | } |
275 | } |
276 | spin_unlock(lock: &cifs_tcp_ses_lock); |
277 | } |
278 | |
279 | static void |
280 | cifs_abort_connection(struct TCP_Server_Info *server) |
281 | { |
282 | struct mid_q_entry *mid, *nmid; |
283 | struct list_head retry_list; |
284 | |
285 | server->maxBuf = 0; |
286 | server->max_read = 0; |
287 | |
288 | /* do not want to be sending data on a socket we are freeing */ |
289 | cifs_dbg(FYI, "%s: tearing down socket\n" , __func__); |
290 | cifs_server_lock(server); |
291 | if (server->ssocket) { |
292 | cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n" , server->ssocket->state, |
293 | server->ssocket->flags); |
294 | kernel_sock_shutdown(sock: server->ssocket, how: SHUT_WR); |
295 | cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n" , server->ssocket->state, |
296 | server->ssocket->flags); |
297 | sock_release(sock: server->ssocket); |
298 | server->ssocket = NULL; |
299 | } |
300 | server->sequence_number = 0; |
301 | server->session_estab = false; |
302 | kfree_sensitive(objp: server->session_key.response); |
303 | server->session_key.response = NULL; |
304 | server->session_key.len = 0; |
305 | server->lstrp = jiffies; |
306 | |
307 | /* mark submitted MIDs for retry and issue callback */ |
308 | INIT_LIST_HEAD(list: &retry_list); |
309 | cifs_dbg(FYI, "%s: moving mids to private list\n" , __func__); |
310 | spin_lock(lock: &server->mid_lock); |
311 | list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) { |
312 | kref_get(kref: &mid->refcount); |
313 | if (mid->mid_state == MID_REQUEST_SUBMITTED) |
314 | mid->mid_state = MID_RETRY_NEEDED; |
315 | list_move(list: &mid->qhead, head: &retry_list); |
316 | mid->mid_flags |= MID_DELETED; |
317 | } |
318 | spin_unlock(lock: &server->mid_lock); |
319 | cifs_server_unlock(server); |
320 | |
321 | cifs_dbg(FYI, "%s: issuing mid callbacks\n" , __func__); |
322 | list_for_each_entry_safe(mid, nmid, &retry_list, qhead) { |
323 | list_del_init(entry: &mid->qhead); |
324 | mid->callback(mid); |
325 | release_mid(mid); |
326 | } |
327 | |
328 | if (cifs_rdma_enabled(server)) { |
329 | cifs_server_lock(server); |
330 | smbd_destroy(server); |
331 | cifs_server_unlock(server); |
332 | } |
333 | } |
334 | |
335 | static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num_targets) |
336 | { |
337 | spin_lock(lock: &server->srv_lock); |
338 | server->nr_targets = num_targets; |
339 | if (server->tcpStatus == CifsExiting) { |
340 | /* the demux thread will exit normally next time through the loop */ |
341 | spin_unlock(lock: &server->srv_lock); |
342 | wake_up(&server->response_q); |
343 | return false; |
344 | } |
345 | |
346 | cifs_dbg(FYI, "Mark tcp session as need reconnect\n" ); |
347 | trace_smb3_reconnect(currmid: server->CurrentMid, conn_id: server->conn_id, |
348 | hostname: server->hostname); |
349 | server->tcpStatus = CifsNeedReconnect; |
350 | |
351 | spin_unlock(lock: &server->srv_lock); |
352 | return true; |
353 | } |
354 | |
355 | /* |
356 | * cifs tcp session reconnection |
357 | * |
358 | * mark tcp session as reconnecting so temporarily locked |
359 | * mark all smb sessions as reconnecting for tcp session |
360 | * reconnect tcp session |
361 | * wake up waiters on reconnection? - (not needed currently) |
362 | * |
363 | * if mark_smb_session is passed as true, unconditionally mark |
364 | * the smb session (and tcon) for reconnect as well. This value |
365 | * doesn't really matter for non-multichannel scenario. |
366 | * |
367 | */ |
368 | static int __cifs_reconnect(struct TCP_Server_Info *server, |
369 | bool mark_smb_session, bool once) |
370 | { |
371 | int rc = 0; |
372 | |
373 | if (!cifs_tcp_ses_needs_reconnect(server, num_targets: 1)) |
374 | return 0; |
375 | |
376 | /* |
377 | * if smb session has been marked for reconnect, also reconnect all |
378 | * connections. This way, the other connections do not end up bad. |
379 | */ |
380 | if (mark_smb_session) |
381 | cifs_signal_cifsd_for_reconnect(server, all_channels: mark_smb_session); |
382 | |
383 | cifs_mark_tcp_ses_conns_for_reconnect(server, mark_smb_session); |
384 | |
385 | cifs_abort_connection(server); |
386 | |
387 | do { |
388 | try_to_freeze(); |
389 | cifs_server_lock(server); |
390 | |
391 | if (!cifs_swn_set_server_dstaddr(server) && |
392 | !SERVER_IS_CHAN(server)) { |
393 | /* resolve the hostname again to make sure that IP address is up-to-date */ |
394 | rc = reconn_set_ipaddr_from_hostname(server); |
395 | cifs_dbg(FYI, "%s: reconn_set_ipaddr_from_hostname: rc=%d\n" , __func__, rc); |
396 | } |
397 | |
398 | if (cifs_rdma_enabled(server)) |
399 | rc = smbd_reconnect(server); |
400 | else |
401 | rc = generic_ip_connect(server); |
402 | if (rc) { |
403 | cifs_server_unlock(server); |
404 | cifs_dbg(FYI, "%s: reconnect error %d\n" , __func__, rc); |
405 | /* If was asked to reconnect only once, do not try it more times */ |
406 | if (once) |
407 | break; |
408 | msleep(msecs: 3000); |
409 | } else { |
410 | atomic_inc(v: &tcpSesReconnectCount); |
411 | set_credits(server, val: 1); |
412 | spin_lock(lock: &server->srv_lock); |
413 | if (server->tcpStatus != CifsExiting) |
414 | server->tcpStatus = CifsNeedNegotiate; |
415 | spin_unlock(lock: &server->srv_lock); |
416 | cifs_swn_reset_server_dstaddr(server); |
417 | cifs_server_unlock(server); |
418 | mod_delayed_work(wq: cifsiod_wq, dwork: &server->reconnect, delay: 0); |
419 | } |
420 | } while (server->tcpStatus == CifsNeedReconnect); |
421 | |
422 | spin_lock(lock: &server->srv_lock); |
423 | if (server->tcpStatus == CifsNeedNegotiate) |
424 | mod_delayed_work(wq: cifsiod_wq, dwork: &server->echo, delay: 0); |
425 | spin_unlock(lock: &server->srv_lock); |
426 | |
427 | wake_up(&server->response_q); |
428 | return rc; |
429 | } |
430 | |
431 | #ifdef CONFIG_CIFS_DFS_UPCALL |
432 | static int __reconnect_target_locked(struct TCP_Server_Info *server, |
433 | const char *target) |
434 | { |
435 | int rc; |
436 | char *hostname; |
437 | |
438 | if (!cifs_swn_set_server_dstaddr(server)) { |
439 | if (server->hostname != target) { |
440 | hostname = extract_hostname(unc: target); |
441 | if (!IS_ERR(ptr: hostname)) { |
442 | spin_lock(lock: &server->srv_lock); |
443 | kfree(objp: server->hostname); |
444 | server->hostname = hostname; |
445 | spin_unlock(lock: &server->srv_lock); |
446 | } else { |
447 | cifs_dbg(FYI, "%s: couldn't extract hostname or address from dfs target: %ld\n" , |
448 | __func__, PTR_ERR(hostname)); |
449 | cifs_dbg(FYI, "%s: default to last target server: %s\n" , __func__, |
450 | server->hostname); |
451 | } |
452 | } |
453 | /* resolve the hostname again to make sure that IP address is up-to-date. */ |
454 | rc = reconn_set_ipaddr_from_hostname(server); |
455 | cifs_dbg(FYI, "%s: reconn_set_ipaddr_from_hostname: rc=%d\n" , __func__, rc); |
456 | } |
457 | /* Reconnect the socket */ |
458 | if (cifs_rdma_enabled(server)) |
459 | rc = smbd_reconnect(server); |
460 | else |
461 | rc = generic_ip_connect(server); |
462 | |
463 | return rc; |
464 | } |
465 | |
466 | static int reconnect_target_locked(struct TCP_Server_Info *server, |
467 | struct dfs_cache_tgt_list *tl, |
468 | struct dfs_cache_tgt_iterator **target_hint) |
469 | { |
470 | struct dfs_cache_tgt_iterator *tit; |
471 | int rc; |
472 | |
473 | *target_hint = NULL; |
474 | |
475 | /* If dfs target list is empty, then reconnect to last server */ |
476 | tit = dfs_cache_get_tgt_iterator(tl); |
477 | if (!tit) |
478 | return __reconnect_target_locked(server, target: server->hostname); |
479 | |
480 | /* Otherwise, try every dfs target in @tl */ |
481 | do { |
482 | const char *target = dfs_cache_get_tgt_name(it: tit); |
483 | |
484 | spin_lock(lock: &server->srv_lock); |
485 | if (server->tcpStatus != CifsNeedReconnect) { |
486 | spin_unlock(lock: &server->srv_lock); |
487 | return -ECONNRESET; |
488 | } |
489 | spin_unlock(lock: &server->srv_lock); |
490 | rc = __reconnect_target_locked(server, target); |
491 | if (!rc) { |
492 | *target_hint = tit; |
493 | break; |
494 | } |
495 | } while ((tit = dfs_cache_get_next_tgt(tl, it: tit))); |
496 | return rc; |
497 | } |
498 | |
499 | static int reconnect_dfs_server(struct TCP_Server_Info *server) |
500 | { |
501 | struct dfs_cache_tgt_iterator *target_hint = NULL; |
502 | const char *ref_path = server->leaf_fullpath + 1; |
503 | DFS_CACHE_TGT_LIST(tl); |
504 | int num_targets = 0; |
505 | int rc = 0; |
506 | |
507 | /* |
508 | * Determine the number of dfs targets the referral path in @cifs_sb resolves to. |
509 | * |
510 | * smb2_reconnect() needs to know how long it should wait based upon the number of dfs |
511 | * targets (server->nr_targets). It's also possible that the cached referral was cleared |
512 | * through /proc/fs/cifs/dfscache or the target list is empty due to server settings after |
513 | * refreshing the referral, so, in this case, default it to 1. |
514 | */ |
515 | if (!dfs_cache_noreq_find(path: ref_path, NULL, tgt_list: &tl)) |
516 | num_targets = dfs_cache_get_nr_tgts(tl: &tl); |
517 | if (!num_targets) |
518 | num_targets = 1; |
519 | |
520 | if (!cifs_tcp_ses_needs_reconnect(server, num_targets)) |
521 | return 0; |
522 | |
523 | /* |
524 | * Unconditionally mark all sessions & tcons for reconnect as we might be connecting to a |
525 | * different server or share during failover. It could be improved by adding some logic to |
526 | * only do that in case it connects to a different server or share, though. |
527 | */ |
528 | cifs_mark_tcp_ses_conns_for_reconnect(server, mark_smb_session: true); |
529 | |
530 | cifs_abort_connection(server); |
531 | |
532 | do { |
533 | try_to_freeze(); |
534 | cifs_server_lock(server); |
535 | |
536 | rc = reconnect_target_locked(server, tl: &tl, target_hint: &target_hint); |
537 | if (rc) { |
538 | /* Failed to reconnect socket */ |
539 | cifs_server_unlock(server); |
540 | cifs_dbg(FYI, "%s: reconnect error %d\n" , __func__, rc); |
541 | msleep(msecs: 3000); |
542 | continue; |
543 | } |
544 | /* |
545 | * Socket was created. Update tcp session status to CifsNeedNegotiate so that a |
546 | * process waiting for reconnect will know it needs to re-establish session and tcon |
547 | * through the reconnected target server. |
548 | */ |
549 | atomic_inc(v: &tcpSesReconnectCount); |
550 | set_credits(server, val: 1); |
551 | spin_lock(lock: &server->srv_lock); |
552 | if (server->tcpStatus != CifsExiting) |
553 | server->tcpStatus = CifsNeedNegotiate; |
554 | spin_unlock(lock: &server->srv_lock); |
555 | cifs_swn_reset_server_dstaddr(server); |
556 | cifs_server_unlock(server); |
557 | mod_delayed_work(wq: cifsiod_wq, dwork: &server->reconnect, delay: 0); |
558 | } while (server->tcpStatus == CifsNeedReconnect); |
559 | |
560 | dfs_cache_noreq_update_tgthint(path: ref_path, it: target_hint); |
561 | dfs_cache_free_tgts(tl: &tl); |
562 | |
563 | /* Need to set up echo worker again once connection has been established */ |
564 | spin_lock(lock: &server->srv_lock); |
565 | if (server->tcpStatus == CifsNeedNegotiate) |
566 | mod_delayed_work(wq: cifsiod_wq, dwork: &server->echo, delay: 0); |
567 | spin_unlock(lock: &server->srv_lock); |
568 | |
569 | wake_up(&server->response_q); |
570 | return rc; |
571 | } |
572 | |
573 | static int |
574 | _cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session, bool once) |
575 | { |
576 | if (!server->leaf_fullpath) |
577 | return __cifs_reconnect(server, mark_smb_session, once); |
578 | return reconnect_dfs_server(server); |
579 | } |
580 | #else |
581 | static int |
582 | _cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session, bool once) |
583 | { |
584 | return __cifs_reconnect(server, mark_smb_session, once); |
585 | } |
586 | #endif |
587 | |
588 | int |
589 | cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session) |
590 | { |
591 | return _cifs_reconnect(server, mark_smb_session, once: false); |
592 | } |
593 | |
594 | static int |
595 | cifs_reconnect_once(struct TCP_Server_Info *server) |
596 | { |
597 | return _cifs_reconnect(server, mark_smb_session: true, once: true); |
598 | } |
599 | |
600 | static void |
601 | cifs_echo_request(struct work_struct *work) |
602 | { |
603 | int rc; |
604 | struct TCP_Server_Info *server = container_of(work, |
605 | struct TCP_Server_Info, echo.work); |
606 | |
607 | /* |
608 | * We cannot send an echo if it is disabled. |
609 | * Also, no need to ping if we got a response recently. |
610 | */ |
611 | |
612 | if (server->tcpStatus == CifsNeedReconnect || |
613 | server->tcpStatus == CifsExiting || |
614 | server->tcpStatus == CifsNew || |
615 | (server->ops->can_echo && !server->ops->can_echo(server)) || |
616 | time_before(jiffies, server->lstrp + server->echo_interval - HZ)) |
617 | goto requeue_echo; |
618 | |
619 | rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS; |
620 | cifs_server_dbg(FYI, "send echo request: rc = %d\n" , rc); |
621 | |
622 | /* Check witness registrations */ |
623 | cifs_swn_check(); |
624 | |
625 | requeue_echo: |
626 | queue_delayed_work(wq: cifsiod_wq, dwork: &server->echo, delay: server->echo_interval); |
627 | } |
628 | |
629 | static bool |
630 | allocate_buffers(struct TCP_Server_Info *server) |
631 | { |
632 | if (!server->bigbuf) { |
633 | server->bigbuf = (char *)cifs_buf_get(); |
634 | if (!server->bigbuf) { |
635 | cifs_server_dbg(VFS, "No memory for large SMB response\n" ); |
636 | msleep(msecs: 3000); |
637 | /* retry will check if exiting */ |
638 | return false; |
639 | } |
640 | } else if (server->large_buf) { |
641 | /* we are reusing a dirty large buf, clear its start */ |
642 | memset(server->bigbuf, 0, HEADER_SIZE(server)); |
643 | } |
644 | |
645 | if (!server->smallbuf) { |
646 | server->smallbuf = (char *)cifs_small_buf_get(); |
647 | if (!server->smallbuf) { |
648 | cifs_server_dbg(VFS, "No memory for SMB response\n" ); |
649 | msleep(msecs: 1000); |
650 | /* retry will check if exiting */ |
651 | return false; |
652 | } |
653 | /* beginning of smb buffer is cleared in our buf_get */ |
654 | } else { |
655 | /* if existing small buf clear beginning */ |
656 | memset(server->smallbuf, 0, HEADER_SIZE(server)); |
657 | } |
658 | |
659 | return true; |
660 | } |
661 | |
662 | static bool |
663 | server_unresponsive(struct TCP_Server_Info *server) |
664 | { |
665 | /* |
666 | * If we're in the process of mounting a share or reconnecting a session |
667 | * and the server abruptly shut down (e.g. socket wasn't closed, packet |
668 | * had been ACK'ed but no SMB response), don't wait longer than 20s to |
669 | * negotiate protocol. |
670 | */ |
671 | spin_lock(lock: &server->srv_lock); |
672 | if (server->tcpStatus == CifsInNegotiate && |
673 | time_after(jiffies, server->lstrp + 20 * HZ)) { |
674 | spin_unlock(lock: &server->srv_lock); |
675 | cifs_reconnect(server, mark_smb_session: false); |
676 | return true; |
677 | } |
678 | /* |
679 | * We need to wait 3 echo intervals to make sure we handle such |
680 | * situations right: |
681 | * 1s client sends a normal SMB request |
682 | * 2s client gets a response |
683 | * 30s echo workqueue job pops, and decides we got a response recently |
684 | * and don't need to send another |
685 | * ... |
686 | * 65s kernel_recvmsg times out, and we see that we haven't gotten |
687 | * a response in >60s. |
688 | */ |
689 | if ((server->tcpStatus == CifsGood || |
690 | server->tcpStatus == CifsNeedNegotiate) && |
691 | (!server->ops->can_echo || server->ops->can_echo(server)) && |
692 | time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { |
693 | spin_unlock(lock: &server->srv_lock); |
694 | cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n" , |
695 | (3 * server->echo_interval) / HZ); |
696 | cifs_reconnect(server, mark_smb_session: false); |
697 | return true; |
698 | } |
699 | spin_unlock(lock: &server->srv_lock); |
700 | |
701 | return false; |
702 | } |
703 | |
704 | static inline bool |
705 | zero_credits(struct TCP_Server_Info *server) |
706 | { |
707 | int val; |
708 | |
709 | spin_lock(lock: &server->req_lock); |
710 | val = server->credits + server->echo_credits + server->oplock_credits; |
711 | if (server->in_flight == 0 && val == 0) { |
712 | spin_unlock(lock: &server->req_lock); |
713 | return true; |
714 | } |
715 | spin_unlock(lock: &server->req_lock); |
716 | return false; |
717 | } |
718 | |
719 | static int |
720 | cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg) |
721 | { |
722 | int length = 0; |
723 | int total_read; |
724 | |
725 | for (total_read = 0; msg_data_left(msg: smb_msg); total_read += length) { |
726 | try_to_freeze(); |
727 | |
728 | /* reconnect if no credits and no requests in flight */ |
729 | if (zero_credits(server)) { |
730 | cifs_reconnect(server, mark_smb_session: false); |
731 | return -ECONNABORTED; |
732 | } |
733 | |
734 | if (server_unresponsive(server)) |
735 | return -ECONNABORTED; |
736 | if (cifs_rdma_enabled(server) && server->smbd_conn) |
737 | length = smbd_recv(info: server->smbd_conn, msg: smb_msg); |
738 | else |
739 | length = sock_recvmsg(sock: server->ssocket, msg: smb_msg, flags: 0); |
740 | |
741 | spin_lock(lock: &server->srv_lock); |
742 | if (server->tcpStatus == CifsExiting) { |
743 | spin_unlock(lock: &server->srv_lock); |
744 | return -ESHUTDOWN; |
745 | } |
746 | |
747 | if (server->tcpStatus == CifsNeedReconnect) { |
748 | spin_unlock(lock: &server->srv_lock); |
749 | cifs_reconnect(server, mark_smb_session: false); |
750 | return -ECONNABORTED; |
751 | } |
752 | spin_unlock(lock: &server->srv_lock); |
753 | |
754 | if (length == -ERESTARTSYS || |
755 | length == -EAGAIN || |
756 | length == -EINTR) { |
757 | /* |
758 | * Minimum sleep to prevent looping, allowing socket |
759 | * to clear and app threads to set tcpStatus |
760 | * CifsNeedReconnect if server hung. |
761 | */ |
762 | usleep_range(min: 1000, max: 2000); |
763 | length = 0; |
764 | continue; |
765 | } |
766 | |
767 | if (length <= 0) { |
768 | cifs_dbg(FYI, "Received no data or error: %d\n" , length); |
769 | cifs_reconnect(server, mark_smb_session: false); |
770 | return -ECONNABORTED; |
771 | } |
772 | } |
773 | return total_read; |
774 | } |
775 | |
776 | int |
777 | cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, |
778 | unsigned int to_read) |
779 | { |
780 | struct msghdr smb_msg = {}; |
781 | struct kvec iov = {.iov_base = buf, .iov_len = to_read}; |
782 | |
783 | iov_iter_kvec(i: &smb_msg.msg_iter, ITER_DEST, kvec: &iov, nr_segs: 1, count: to_read); |
784 | |
785 | return cifs_readv_from_socket(server, smb_msg: &smb_msg); |
786 | } |
787 | |
788 | ssize_t |
789 | cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read) |
790 | { |
791 | struct msghdr smb_msg = {}; |
792 | |
793 | /* |
794 | * iov_iter_discard already sets smb_msg.type and count and iov_offset |
795 | * and cifs_readv_from_socket sets msg_control and msg_controllen |
796 | * so little to initialize in struct msghdr |
797 | */ |
798 | iov_iter_discard(i: &smb_msg.msg_iter, ITER_DEST, count: to_read); |
799 | |
800 | return cifs_readv_from_socket(server, smb_msg: &smb_msg); |
801 | } |
802 | |
803 | int |
804 | cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter, |
805 | unsigned int to_read) |
806 | { |
807 | struct msghdr smb_msg = { .msg_iter = *iter }; |
808 | |
809 | iov_iter_truncate(i: &smb_msg.msg_iter, count: to_read); |
810 | return cifs_readv_from_socket(server, smb_msg: &smb_msg); |
811 | } |
812 | |
813 | static bool |
814 | is_smb_response(struct TCP_Server_Info *server, unsigned char type) |
815 | { |
816 | /* |
817 | * The first byte big endian of the length field, |
818 | * is actually not part of the length but the type |
819 | * with the most common, zero, as regular data. |
820 | */ |
821 | switch (type) { |
822 | case RFC1002_SESSION_MESSAGE: |
823 | /* Regular SMB response */ |
824 | return true; |
825 | case RFC1002_SESSION_KEEP_ALIVE: |
826 | /* |
827 | * RFC 1002 session keep alive can sent by the server only when |
828 | * we established a RFC 1002 session. But Samba servers send |
829 | * RFC 1002 session keep alive also over port 445 on which |
830 | * RFC 1002 session is not established. |
831 | */ |
832 | cifs_dbg(FYI, "RFC 1002 session keep alive\n" ); |
833 | break; |
834 | case RFC1002_POSITIVE_SESSION_RESPONSE: |
835 | /* |
836 | * RFC 1002 positive session response cannot be returned |
837 | * for SMB request. RFC 1002 session response is handled |
838 | * exclusively in ip_rfc1001_connect() function. |
839 | */ |
840 | cifs_server_dbg(VFS, "RFC 1002 positive session response (unexpected)\n" ); |
841 | cifs_reconnect(server, mark_smb_session: true); |
842 | break; |
843 | case RFC1002_NEGATIVE_SESSION_RESPONSE: |
844 | /* |
845 | * We get this from Windows 98 instead of an error on |
846 | * SMB negprot response, when we have not established |
847 | * RFC 1002 session (which means ip_rfc1001_connect() |
848 | * was skipped). Note that same still happens with |
849 | * Windows Server 2022 when connecting via port 139. |
850 | * So for this case when mount option -o nonbsessinit |
851 | * was not specified, try to reconnect with establishing |
852 | * RFC 1002 session. If new socket establishment with |
853 | * RFC 1002 session was successful then return to the |
854 | * mid's caller -EAGAIN, so it can retry the request. |
855 | */ |
856 | if (!cifs_rdma_enabled(server) && |
857 | server->tcpStatus == CifsInNegotiate && |
858 | !server->with_rfc1001 && |
859 | server->rfc1001_sessinit != 0) { |
860 | int rc, mid_rc; |
861 | struct mid_q_entry *mid, *nmid; |
862 | LIST_HEAD(dispose_list); |
863 | |
864 | cifs_dbg(FYI, "RFC 1002 negative session response during SMB Negotiate, retrying with NetBIOS session\n" ); |
865 | |
866 | /* |
867 | * Before reconnect, delete all pending mids for this |
868 | * server, so reconnect would not signal connection |
869 | * aborted error to mid's callbacks. Note that for this |
870 | * server there should be exactly one pending mid |
871 | * corresponding to SMB1/SMB2 Negotiate packet. |
872 | */ |
873 | spin_lock(lock: &server->mid_lock); |
874 | list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) { |
875 | kref_get(kref: &mid->refcount); |
876 | list_move(list: &mid->qhead, head: &dispose_list); |
877 | mid->mid_flags |= MID_DELETED; |
878 | } |
879 | spin_unlock(lock: &server->mid_lock); |
880 | |
881 | /* Now try to reconnect once with NetBIOS session. */ |
882 | server->with_rfc1001 = true; |
883 | rc = cifs_reconnect_once(server); |
884 | |
885 | /* |
886 | * If reconnect was successful then indicate -EAGAIN |
887 | * to mid's caller. If reconnect failed with -EAGAIN |
888 | * then mask it as -EHOSTDOWN, so mid's caller would |
889 | * know that it failed. |
890 | */ |
891 | if (rc == 0) |
892 | mid_rc = -EAGAIN; |
893 | else if (rc == -EAGAIN) |
894 | mid_rc = -EHOSTDOWN; |
895 | else |
896 | mid_rc = rc; |
897 | |
898 | /* |
899 | * After reconnect (either successful or unsuccessful) |
900 | * deliver reconnect status to mid's caller via mid's |
901 | * callback. Use MID_RC state which indicates that the |
902 | * return code should be read from mid_rc member. |
903 | */ |
904 | list_for_each_entry_safe(mid, nmid, &dispose_list, qhead) { |
905 | list_del_init(entry: &mid->qhead); |
906 | mid->mid_rc = mid_rc; |
907 | mid->mid_state = MID_RC; |
908 | mid->callback(mid); |
909 | release_mid(mid); |
910 | } |
911 | |
912 | /* |
913 | * If reconnect failed then wait two seconds. In most |
914 | * cases we were been called from the mount context and |
915 | * delivered failure to mid's callback will stop this |
916 | * receiver task thread and fails the mount process. |
917 | * So wait two seconds to prevent another reconnect |
918 | * in this task thread, which would be useless as the |
919 | * mount context will fail at all. |
920 | */ |
921 | if (rc != 0) |
922 | msleep(msecs: 2000); |
923 | } else { |
924 | cifs_server_dbg(VFS, "RFC 1002 negative session response (unexpected)\n" ); |
925 | cifs_reconnect(server, mark_smb_session: true); |
926 | } |
927 | break; |
928 | case RFC1002_RETARGET_SESSION_RESPONSE: |
929 | cifs_server_dbg(VFS, "RFC 1002 retarget session response (unexpected)\n" ); |
930 | cifs_reconnect(server, mark_smb_session: true); |
931 | break; |
932 | default: |
933 | cifs_server_dbg(VFS, "RFC 1002 unknown response type 0x%x\n" , type); |
934 | cifs_reconnect(server, mark_smb_session: true); |
935 | } |
936 | |
937 | return false; |
938 | } |
939 | |
940 | void |
941 | dequeue_mid(struct mid_q_entry *mid, bool malformed) |
942 | { |
943 | #ifdef CONFIG_CIFS_STATS2 |
944 | mid->when_received = jiffies; |
945 | #endif |
946 | spin_lock(lock: &mid->server->mid_lock); |
947 | if (!malformed) |
948 | mid->mid_state = MID_RESPONSE_RECEIVED; |
949 | else |
950 | mid->mid_state = MID_RESPONSE_MALFORMED; |
951 | /* |
952 | * Trying to handle/dequeue a mid after the send_recv() |
953 | * function has finished processing it is a bug. |
954 | */ |
955 | if (mid->mid_flags & MID_DELETED) { |
956 | spin_unlock(lock: &mid->server->mid_lock); |
957 | pr_warn_once("trying to dequeue a deleted mid\n" ); |
958 | } else { |
959 | list_del_init(entry: &mid->qhead); |
960 | mid->mid_flags |= MID_DELETED; |
961 | spin_unlock(lock: &mid->server->mid_lock); |
962 | } |
963 | } |
964 | |
965 | static unsigned int |
966 | smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) |
967 | { |
968 | struct smb2_hdr *shdr = (struct smb2_hdr *)buffer; |
969 | |
970 | /* |
971 | * SMB1 does not use credits. |
972 | */ |
973 | if (is_smb1(server)) |
974 | return 0; |
975 | |
976 | return le16_to_cpu(shdr->CreditRequest); |
977 | } |
978 | |
979 | static void |
980 | handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, |
981 | char *buf, int malformed) |
982 | { |
983 | if (server->ops->check_trans2 && |
984 | server->ops->check_trans2(mid, server, buf, malformed)) |
985 | return; |
986 | mid->credits_received = smb2_get_credits_from_hdr(buffer: buf, server); |
987 | mid->resp_buf = buf; |
988 | mid->large_buf = server->large_buf; |
989 | /* Was previous buf put in mpx struct for multi-rsp? */ |
990 | if (!mid->multiRsp) { |
991 | /* smb buffer will be freed by user thread */ |
992 | if (server->large_buf) |
993 | server->bigbuf = NULL; |
994 | else |
995 | server->smallbuf = NULL; |
996 | } |
997 | dequeue_mid(mid, malformed); |
998 | } |
999 | |
1000 | int |
1001 | cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required) |
1002 | { |
1003 | bool srv_sign_required = server->sec_mode & server->vals->signing_required; |
1004 | bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled; |
1005 | bool mnt_sign_enabled; |
1006 | |
1007 | /* |
1008 | * Is signing required by mnt options? If not then check |
1009 | * global_secflags to see if it is there. |
1010 | */ |
1011 | if (!mnt_sign_required) |
1012 | mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) == |
1013 | CIFSSEC_MUST_SIGN); |
1014 | |
1015 | /* |
1016 | * If signing is required then it's automatically enabled too, |
1017 | * otherwise, check to see if the secflags allow it. |
1018 | */ |
1019 | mnt_sign_enabled = mnt_sign_required ? mnt_sign_required : |
1020 | (global_secflags & CIFSSEC_MAY_SIGN); |
1021 | |
1022 | /* If server requires signing, does client allow it? */ |
1023 | if (srv_sign_required) { |
1024 | if (!mnt_sign_enabled) { |
1025 | cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n" ); |
1026 | return -EOPNOTSUPP; |
1027 | } |
1028 | server->sign = true; |
1029 | } |
1030 | |
1031 | /* If client requires signing, does server allow it? */ |
1032 | if (mnt_sign_required) { |
1033 | if (!srv_sign_enabled) { |
1034 | cifs_dbg(VFS, "Server does not support signing!\n" ); |
1035 | return -EOPNOTSUPP; |
1036 | } |
1037 | server->sign = true; |
1038 | } |
1039 | |
1040 | if (cifs_rdma_enabled(server) && server->sign) |
1041 | cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n" ); |
1042 | |
1043 | return 0; |
1044 | } |
1045 | |
1046 | static noinline_for_stack void |
1047 | clean_demultiplex_info(struct TCP_Server_Info *server) |
1048 | { |
1049 | int length; |
1050 | |
1051 | /* take it off the list, if it's not already */ |
1052 | spin_lock(lock: &server->srv_lock); |
1053 | list_del_init(entry: &server->tcp_ses_list); |
1054 | spin_unlock(lock: &server->srv_lock); |
1055 | |
1056 | cancel_delayed_work_sync(dwork: &server->echo); |
1057 | |
1058 | spin_lock(lock: &server->srv_lock); |
1059 | server->tcpStatus = CifsExiting; |
1060 | spin_unlock(lock: &server->srv_lock); |
1061 | wake_up_all(&server->response_q); |
1062 | |
1063 | /* check if we have blocked requests that need to free */ |
1064 | spin_lock(lock: &server->req_lock); |
1065 | if (server->credits <= 0) |
1066 | server->credits = 1; |
1067 | spin_unlock(lock: &server->req_lock); |
1068 | /* |
1069 | * Although there should not be any requests blocked on this queue it |
1070 | * can not hurt to be paranoid and try to wake up requests that may |
1071 | * haven been blocked when more than 50 at time were on the wire to the |
1072 | * same server - they now will see the session is in exit state and get |
1073 | * out of SendReceive. |
1074 | */ |
1075 | wake_up_all(&server->request_q); |
1076 | /* give those requests time to exit */ |
1077 | msleep(msecs: 125); |
1078 | if (cifs_rdma_enabled(server)) |
1079 | smbd_destroy(server); |
1080 | if (server->ssocket) { |
1081 | sock_release(sock: server->ssocket); |
1082 | server->ssocket = NULL; |
1083 | } |
1084 | |
1085 | if (!list_empty(head: &server->pending_mid_q)) { |
1086 | struct mid_q_entry *mid_entry; |
1087 | struct list_head *tmp, *tmp2; |
1088 | LIST_HEAD(dispose_list); |
1089 | |
1090 | spin_lock(lock: &server->mid_lock); |
1091 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { |
1092 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
1093 | cifs_dbg(FYI, "Clearing mid %llu\n" , mid_entry->mid); |
1094 | kref_get(kref: &mid_entry->refcount); |
1095 | mid_entry->mid_state = MID_SHUTDOWN; |
1096 | list_move(list: &mid_entry->qhead, head: &dispose_list); |
1097 | mid_entry->mid_flags |= MID_DELETED; |
1098 | } |
1099 | spin_unlock(lock: &server->mid_lock); |
1100 | |
1101 | /* now walk dispose list and issue callbacks */ |
1102 | list_for_each_safe(tmp, tmp2, &dispose_list) { |
1103 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
1104 | cifs_dbg(FYI, "Callback mid %llu\n" , mid_entry->mid); |
1105 | list_del_init(entry: &mid_entry->qhead); |
1106 | mid_entry->callback(mid_entry); |
1107 | release_mid(mid: mid_entry); |
1108 | } |
1109 | /* 1/8th of sec is more than enough time for them to exit */ |
1110 | msleep(msecs: 125); |
1111 | } |
1112 | |
1113 | if (!list_empty(head: &server->pending_mid_q)) { |
1114 | /* |
1115 | * mpx threads have not exited yet give them at least the smb |
1116 | * send timeout time for long ops. |
1117 | * |
1118 | * Due to delays on oplock break requests, we need to wait at |
1119 | * least 45 seconds before giving up on a request getting a |
1120 | * response and going ahead and killing cifsd. |
1121 | */ |
1122 | cifs_dbg(FYI, "Wait for exit from demultiplex thread\n" ); |
1123 | msleep(msecs: 46000); |
1124 | /* |
1125 | * If threads still have not exited they are probably never |
1126 | * coming home not much else we can do but free the memory. |
1127 | */ |
1128 | } |
1129 | |
1130 | put_net(net: cifs_net_ns(srv: server)); |
1131 | kfree(objp: server->leaf_fullpath); |
1132 | kfree(objp: server->hostname); |
1133 | kfree(objp: server); |
1134 | |
1135 | length = atomic_dec_return(v: &tcpSesAllocCount); |
1136 | if (length > 0) |
1137 | mempool_resize(pool: cifs_req_poolp, new_min_nr: length + cifs_min_rcv); |
1138 | } |
1139 | |
1140 | static int |
1141 | standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) |
1142 | { |
1143 | int length; |
1144 | char *buf = server->smallbuf; |
1145 | unsigned int pdu_length = server->pdu_size; |
1146 | |
1147 | /* make sure this will fit in a large buffer */ |
1148 | if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - |
1149 | HEADER_PREAMBLE_SIZE(server)) { |
1150 | cifs_server_dbg(VFS, "SMB response too long (%u bytes)\n" , pdu_length); |
1151 | cifs_reconnect(server, mark_smb_session: true); |
1152 | return -ECONNABORTED; |
1153 | } |
1154 | |
1155 | /* switch to large buffer if too big for a small one */ |
1156 | if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { |
1157 | server->large_buf = true; |
1158 | memcpy(server->bigbuf, buf, server->total_read); |
1159 | buf = server->bigbuf; |
1160 | } |
1161 | |
1162 | /* now read the rest */ |
1163 | length = cifs_read_from_socket(server, buf: buf + HEADER_SIZE(server) - 1, |
1164 | to_read: pdu_length - MID_HEADER_SIZE(server)); |
1165 | |
1166 | if (length < 0) |
1167 | return length; |
1168 | server->total_read += length; |
1169 | |
1170 | dump_smb(buf, server->total_read); |
1171 | |
1172 | return cifs_handle_standard(server, mid); |
1173 | } |
1174 | |
1175 | int |
1176 | cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid) |
1177 | { |
1178 | char *buf = server->large_buf ? server->bigbuf : server->smallbuf; |
1179 | int rc; |
1180 | |
1181 | /* |
1182 | * We know that we received enough to get to the MID as we |
1183 | * checked the pdu_length earlier. Now check to see |
1184 | * if the rest of the header is OK. |
1185 | * |
1186 | * 48 bytes is enough to display the header and a little bit |
1187 | * into the payload for debugging purposes. |
1188 | */ |
1189 | rc = server->ops->check_message(buf, server->total_read, server); |
1190 | if (rc) |
1191 | cifs_dump_mem(label: "Bad SMB: " , data: buf, |
1192 | min_t(unsigned int, server->total_read, 48)); |
1193 | |
1194 | if (server->ops->is_session_expired && |
1195 | server->ops->is_session_expired(buf)) { |
1196 | cifs_reconnect(server, mark_smb_session: true); |
1197 | return -1; |
1198 | } |
1199 | |
1200 | if (server->ops->is_status_pending && |
1201 | server->ops->is_status_pending(buf, server)) |
1202 | return -1; |
1203 | |
1204 | if (!mid) |
1205 | return rc; |
1206 | |
1207 | handle_mid(mid, server, buf, malformed: rc); |
1208 | return 0; |
1209 | } |
1210 | |
1211 | static void |
1212 | smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) |
1213 | { |
1214 | struct smb2_hdr *shdr = (struct smb2_hdr *)buffer; |
1215 | int scredits, in_flight; |
1216 | |
1217 | /* |
1218 | * SMB1 does not use credits. |
1219 | */ |
1220 | if (is_smb1(server)) |
1221 | return; |
1222 | |
1223 | if (shdr->CreditRequest) { |
1224 | spin_lock(lock: &server->req_lock); |
1225 | server->credits += le16_to_cpu(shdr->CreditRequest); |
1226 | scredits = server->credits; |
1227 | in_flight = server->in_flight; |
1228 | spin_unlock(lock: &server->req_lock); |
1229 | wake_up(&server->request_q); |
1230 | |
1231 | trace_smb3_hdr_credits(currmid: server->CurrentMid, |
1232 | conn_id: server->conn_id, hostname: server->hostname, credits: scredits, |
1233 | le16_to_cpu(shdr->CreditRequest), in_flight); |
1234 | cifs_server_dbg(FYI, "%s: added %u credits total=%d\n" , |
1235 | __func__, le16_to_cpu(shdr->CreditRequest), |
1236 | scredits); |
1237 | } |
1238 | } |
1239 | |
1240 | |
1241 | static int |
1242 | cifs_demultiplex_thread(void *p) |
1243 | { |
1244 | int i, num_mids, length; |
1245 | struct TCP_Server_Info *server = p; |
1246 | unsigned int pdu_length; |
1247 | unsigned int next_offset; |
1248 | char *buf = NULL; |
1249 | struct task_struct *task_to_wake = NULL; |
1250 | struct mid_q_entry *mids[MAX_COMPOUND]; |
1251 | char *bufs[MAX_COMPOUND]; |
1252 | unsigned int noreclaim_flag, num_io_timeout = 0; |
1253 | bool pending_reconnect = false; |
1254 | |
1255 | noreclaim_flag = memalloc_noreclaim_save(); |
1256 | cifs_dbg(FYI, "Demultiplex PID: %d\n" , task_pid_nr(current)); |
1257 | |
1258 | length = atomic_inc_return(v: &tcpSesAllocCount); |
1259 | if (length > 1) |
1260 | mempool_resize(pool: cifs_req_poolp, new_min_nr: length + cifs_min_rcv); |
1261 | |
1262 | set_freezable(); |
1263 | allow_kernel_signal(SIGKILL); |
1264 | while (server->tcpStatus != CifsExiting) { |
1265 | if (try_to_freeze()) |
1266 | continue; |
1267 | |
1268 | if (!allocate_buffers(server)) |
1269 | continue; |
1270 | |
1271 | server->large_buf = false; |
1272 | buf = server->smallbuf; |
1273 | pdu_length = 4; /* enough to get RFC1001 header */ |
1274 | |
1275 | length = cifs_read_from_socket(server, buf, to_read: pdu_length); |
1276 | if (length < 0) |
1277 | continue; |
1278 | |
1279 | if (is_smb1(server)) |
1280 | server->total_read = length; |
1281 | else |
1282 | server->total_read = 0; |
1283 | |
1284 | /* |
1285 | * The right amount was read from socket - 4 bytes, |
1286 | * so we can now interpret the length field. |
1287 | */ |
1288 | pdu_length = get_rfc1002_length(buf); |
1289 | |
1290 | cifs_dbg(FYI, "RFC1002 header 0x%x\n" , pdu_length); |
1291 | if (!is_smb_response(server, type: buf[0])) |
1292 | continue; |
1293 | |
1294 | pending_reconnect = false; |
1295 | next_pdu: |
1296 | server->pdu_size = pdu_length; |
1297 | |
1298 | /* make sure we have enough to get to the MID */ |
1299 | if (server->pdu_size < MID_HEADER_SIZE(server)) { |
1300 | cifs_server_dbg(VFS, "SMB response too short (%u bytes)\n" , |
1301 | server->pdu_size); |
1302 | cifs_reconnect(server, mark_smb_session: true); |
1303 | continue; |
1304 | } |
1305 | |
1306 | /* read down to the MID */ |
1307 | length = cifs_read_from_socket(server, |
1308 | buf: buf + HEADER_PREAMBLE_SIZE(server), |
1309 | MID_HEADER_SIZE(server)); |
1310 | if (length < 0) |
1311 | continue; |
1312 | server->total_read += length; |
1313 | |
1314 | if (server->ops->next_header) { |
1315 | if (server->ops->next_header(server, buf, &next_offset)) { |
1316 | cifs_dbg(VFS, "%s: malformed response (next_offset=%u)\n" , |
1317 | __func__, next_offset); |
1318 | cifs_reconnect(server, mark_smb_session: true); |
1319 | continue; |
1320 | } |
1321 | if (next_offset) |
1322 | server->pdu_size = next_offset; |
1323 | } |
1324 | |
1325 | memset(mids, 0, sizeof(mids)); |
1326 | memset(bufs, 0, sizeof(bufs)); |
1327 | num_mids = 0; |
1328 | |
1329 | if (server->ops->is_transform_hdr && |
1330 | server->ops->receive_transform && |
1331 | server->ops->is_transform_hdr(buf)) { |
1332 | length = server->ops->receive_transform(server, |
1333 | mids, |
1334 | bufs, |
1335 | &num_mids); |
1336 | } else { |
1337 | mids[0] = server->ops->find_mid(server, buf); |
1338 | bufs[0] = buf; |
1339 | num_mids = 1; |
1340 | |
1341 | if (!mids[0] || !mids[0]->receive) |
1342 | length = standard_receive3(server, mid: mids[0]); |
1343 | else |
1344 | length = mids[0]->receive(server, mids[0]); |
1345 | } |
1346 | |
1347 | if (length < 0) { |
1348 | for (i = 0; i < num_mids; i++) |
1349 | if (mids[i]) |
1350 | release_mid(mid: mids[i]); |
1351 | continue; |
1352 | } |
1353 | |
1354 | if (server->ops->is_status_io_timeout && |
1355 | server->ops->is_status_io_timeout(buf)) { |
1356 | num_io_timeout++; |
1357 | if (num_io_timeout > MAX_STATUS_IO_TIMEOUT) { |
1358 | cifs_server_dbg(VFS, |
1359 | "Number of request timeouts exceeded %d. Reconnecting" , |
1360 | MAX_STATUS_IO_TIMEOUT); |
1361 | |
1362 | pending_reconnect = true; |
1363 | num_io_timeout = 0; |
1364 | } |
1365 | } |
1366 | |
1367 | server->lstrp = jiffies; |
1368 | |
1369 | for (i = 0; i < num_mids; i++) { |
1370 | if (mids[i] != NULL) { |
1371 | mids[i]->resp_buf_size = server->pdu_size; |
1372 | |
1373 | if (bufs[i] != NULL) { |
1374 | if (server->ops->is_network_name_deleted && |
1375 | server->ops->is_network_name_deleted(bufs[i], |
1376 | server)) { |
1377 | cifs_server_dbg(FYI, |
1378 | "Share deleted. Reconnect needed" ); |
1379 | } |
1380 | } |
1381 | |
1382 | if (!mids[i]->multiRsp || mids[i]->multiEnd) |
1383 | mids[i]->callback(mids[i]); |
1384 | |
1385 | release_mid(mid: mids[i]); |
1386 | } else if (server->ops->is_oplock_break && |
1387 | server->ops->is_oplock_break(bufs[i], |
1388 | server)) { |
1389 | smb2_add_credits_from_hdr(buffer: bufs[i], server); |
1390 | cifs_dbg(FYI, "Received oplock break\n" ); |
1391 | } else { |
1392 | cifs_server_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n" , |
1393 | atomic_read(&mid_count)); |
1394 | cifs_dump_mem(label: "Received Data is: " , data: bufs[i], |
1395 | HEADER_SIZE(server)); |
1396 | smb2_add_credits_from_hdr(buffer: bufs[i], server); |
1397 | #ifdef CONFIG_CIFS_DEBUG2 |
1398 | if (server->ops->dump_detail) |
1399 | server->ops->dump_detail(bufs[i], |
1400 | server); |
1401 | cifs_dump_mids(server); |
1402 | #endif /* CIFS_DEBUG2 */ |
1403 | } |
1404 | } |
1405 | |
1406 | if (pdu_length > server->pdu_size) { |
1407 | if (!allocate_buffers(server)) |
1408 | continue; |
1409 | pdu_length -= server->pdu_size; |
1410 | server->total_read = 0; |
1411 | server->large_buf = false; |
1412 | buf = server->smallbuf; |
1413 | goto next_pdu; |
1414 | } |
1415 | |
1416 | /* do this reconnect at the very end after processing all MIDs */ |
1417 | if (pending_reconnect) |
1418 | cifs_reconnect(server, mark_smb_session: true); |
1419 | |
1420 | } /* end while !EXITING */ |
1421 | |
1422 | /* buffer usually freed in free_mid - need to free it here on exit */ |
1423 | cifs_buf_release(server->bigbuf); |
1424 | if (server->smallbuf) /* no sense logging a debug message if NULL */ |
1425 | cifs_small_buf_release(server->smallbuf); |
1426 | |
1427 | task_to_wake = xchg(&server->tsk, NULL); |
1428 | clean_demultiplex_info(server); |
1429 | |
1430 | /* if server->tsk was NULL then wait for a signal before exiting */ |
1431 | if (!task_to_wake) { |
1432 | set_current_state(TASK_INTERRUPTIBLE); |
1433 | while (!signal_pending(current)) { |
1434 | schedule(); |
1435 | set_current_state(TASK_INTERRUPTIBLE); |
1436 | } |
1437 | set_current_state(TASK_RUNNING); |
1438 | } |
1439 | |
1440 | memalloc_noreclaim_restore(flags: noreclaim_flag); |
1441 | module_put_and_kthread_exit(0); |
1442 | } |
1443 | |
1444 | int |
1445 | cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs) |
1446 | { |
1447 | struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr; |
1448 | struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs; |
1449 | struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr; |
1450 | struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs; |
1451 | |
1452 | switch (srcaddr->sa_family) { |
1453 | case AF_UNSPEC: |
1454 | switch (rhs->sa_family) { |
1455 | case AF_UNSPEC: |
1456 | return 0; |
1457 | case AF_INET: |
1458 | case AF_INET6: |
1459 | return 1; |
1460 | default: |
1461 | return -1; |
1462 | } |
1463 | case AF_INET: { |
1464 | switch (rhs->sa_family) { |
1465 | case AF_UNSPEC: |
1466 | return -1; |
1467 | case AF_INET: |
1468 | return memcmp(p: saddr4, q: vaddr4, |
1469 | size: sizeof(struct sockaddr_in)); |
1470 | case AF_INET6: |
1471 | return 1; |
1472 | default: |
1473 | return -1; |
1474 | } |
1475 | } |
1476 | case AF_INET6: { |
1477 | switch (rhs->sa_family) { |
1478 | case AF_UNSPEC: |
1479 | case AF_INET: |
1480 | return -1; |
1481 | case AF_INET6: |
1482 | return memcmp(p: saddr6, |
1483 | q: vaddr6, |
1484 | size: sizeof(struct sockaddr_in6)); |
1485 | default: |
1486 | return -1; |
1487 | } |
1488 | } |
1489 | default: |
1490 | return -1; /* don't expect to be here */ |
1491 | } |
1492 | } |
1493 | |
1494 | /* |
1495 | * Returns true if srcaddr isn't specified and rhs isn't specified, or |
1496 | * if srcaddr is specified and matches the IP address of the rhs argument |
1497 | */ |
1498 | bool |
1499 | cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs) |
1500 | { |
1501 | switch (srcaddr->sa_family) { |
1502 | case AF_UNSPEC: |
1503 | return (rhs->sa_family == AF_UNSPEC); |
1504 | case AF_INET: { |
1505 | struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr; |
1506 | struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs; |
1507 | |
1508 | return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr); |
1509 | } |
1510 | case AF_INET6: { |
1511 | struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr; |
1512 | struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs; |
1513 | |
1514 | return (ipv6_addr_equal(a1: &saddr6->sin6_addr, a2: &vaddr6->sin6_addr) |
1515 | && saddr6->sin6_scope_id == vaddr6->sin6_scope_id); |
1516 | } |
1517 | default: |
1518 | WARN_ON(1); |
1519 | return false; /* don't expect to be here */ |
1520 | } |
1521 | } |
1522 | |
1523 | /* |
1524 | * If no port is specified in addr structure, we try to match with 445 port |
1525 | * and if it fails - with 139 ports. It should be called only if address |
1526 | * families of server and addr are equal. |
1527 | */ |
1528 | static bool |
1529 | match_port(struct TCP_Server_Info *server, struct sockaddr *addr) |
1530 | { |
1531 | __be16 port, *sport; |
1532 | |
1533 | /* SMBDirect manages its own ports, don't match it here */ |
1534 | if (server->rdma) |
1535 | return true; |
1536 | |
1537 | switch (addr->sa_family) { |
1538 | case AF_INET: |
1539 | sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port; |
1540 | port = ((struct sockaddr_in *) addr)->sin_port; |
1541 | break; |
1542 | case AF_INET6: |
1543 | sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port; |
1544 | port = ((struct sockaddr_in6 *) addr)->sin6_port; |
1545 | break; |
1546 | default: |
1547 | WARN_ON(1); |
1548 | return false; |
1549 | } |
1550 | |
1551 | if (!port) { |
1552 | port = htons(CIFS_PORT); |
1553 | if (port == *sport) |
1554 | return true; |
1555 | |
1556 | port = htons(RFC1001_PORT); |
1557 | } |
1558 | |
1559 | return port == *sport; |
1560 | } |
1561 | |
1562 | static bool match_server_address(struct TCP_Server_Info *server, struct sockaddr *addr) |
1563 | { |
1564 | if (!cifs_match_ipaddr(srcaddr: addr, rhs: (struct sockaddr *)&server->dstaddr)) |
1565 | return false; |
1566 | |
1567 | return true; |
1568 | } |
1569 | |
1570 | static bool |
1571 | match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) |
1572 | { |
1573 | /* |
1574 | * The select_sectype function should either return the ctx->sectype |
1575 | * that was specified, or "Unspecified" if that sectype was not |
1576 | * compatible with the given NEGOTIATE request. |
1577 | */ |
1578 | if (server->ops->select_sectype(server, ctx->sectype) |
1579 | == Unspecified) |
1580 | return false; |
1581 | |
1582 | /* |
1583 | * Now check if signing mode is acceptable. No need to check |
1584 | * global_secflags at this point since if MUST_SIGN is set then |
1585 | * the server->sign had better be too. |
1586 | */ |
1587 | if (ctx->sign && !server->sign) |
1588 | return false; |
1589 | |
1590 | return true; |
1591 | } |
1592 | |
1593 | /* this function must be called with srv_lock held */ |
1594 | static int match_server(struct TCP_Server_Info *server, |
1595 | struct smb3_fs_context *ctx, |
1596 | bool match_super) |
1597 | { |
1598 | struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr; |
1599 | |
1600 | lockdep_assert_held(&server->srv_lock); |
1601 | |
1602 | if (ctx->nosharesock) |
1603 | return 0; |
1604 | |
1605 | /* this server does not share socket */ |
1606 | if (server->nosharesock) |
1607 | return 0; |
1608 | |
1609 | if (!match_super && (ctx->dfs_conn || server->dfs_conn)) |
1610 | return 0; |
1611 | |
1612 | /* If multidialect negotiation see if existing sessions match one */ |
1613 | if (strcmp(ctx->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { |
1614 | if (server->vals->protocol_id < SMB30_PROT_ID) |
1615 | return 0; |
1616 | } else if (strcmp(ctx->vals->version_string, |
1617 | SMBDEFAULT_VERSION_STRING) == 0) { |
1618 | if (server->vals->protocol_id < SMB21_PROT_ID) |
1619 | return 0; |
1620 | } else if ((server->vals != ctx->vals) || (server->ops != ctx->ops)) |
1621 | return 0; |
1622 | |
1623 | if (!net_eq(net1: cifs_net_ns(srv: server), current->nsproxy->net_ns)) |
1624 | return 0; |
1625 | |
1626 | if (!cifs_match_ipaddr(srcaddr: (struct sockaddr *)&ctx->srcaddr, |
1627 | rhs: (struct sockaddr *)&server->srcaddr)) |
1628 | return 0; |
1629 | |
1630 | if (strcasecmp(s1: server->hostname, s2: ctx->server_hostname) || |
1631 | !match_server_address(server, addr) || |
1632 | !match_port(server, addr)) |
1633 | return 0; |
1634 | |
1635 | if (!match_security(server, ctx)) |
1636 | return 0; |
1637 | |
1638 | if (server->echo_interval != ctx->echo_interval * HZ) |
1639 | return 0; |
1640 | |
1641 | if (server->rdma != ctx->rdma) |
1642 | return 0; |
1643 | |
1644 | if (server->ignore_signature != ctx->ignore_signature) |
1645 | return 0; |
1646 | |
1647 | if (server->min_offload != ctx->min_offload) |
1648 | return 0; |
1649 | |
1650 | if (server->retrans != ctx->retrans) |
1651 | return 0; |
1652 | |
1653 | return 1; |
1654 | } |
1655 | |
1656 | struct TCP_Server_Info * |
1657 | cifs_find_tcp_session(struct smb3_fs_context *ctx) |
1658 | { |
1659 | struct TCP_Server_Info *server; |
1660 | |
1661 | spin_lock(lock: &cifs_tcp_ses_lock); |
1662 | list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { |
1663 | spin_lock(lock: &server->srv_lock); |
1664 | /* |
1665 | * Skip ses channels since they're only handled in lower layers |
1666 | * (e.g. cifs_send_recv). |
1667 | */ |
1668 | if (SERVER_IS_CHAN(server) || |
1669 | !match_server(server, ctx, match_super: false)) { |
1670 | spin_unlock(lock: &server->srv_lock); |
1671 | continue; |
1672 | } |
1673 | spin_unlock(lock: &server->srv_lock); |
1674 | |
1675 | ++server->srv_count; |
1676 | spin_unlock(lock: &cifs_tcp_ses_lock); |
1677 | cifs_dbg(FYI, "Existing tcp session with server found\n" ); |
1678 | return server; |
1679 | } |
1680 | spin_unlock(lock: &cifs_tcp_ses_lock); |
1681 | return NULL; |
1682 | } |
1683 | |
1684 | void |
1685 | cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) |
1686 | { |
1687 | struct task_struct *task; |
1688 | |
1689 | spin_lock(lock: &cifs_tcp_ses_lock); |
1690 | if (--server->srv_count > 0) { |
1691 | spin_unlock(lock: &cifs_tcp_ses_lock); |
1692 | return; |
1693 | } |
1694 | |
1695 | /* srv_count can never go negative */ |
1696 | WARN_ON(server->srv_count < 0); |
1697 | |
1698 | list_del_init(entry: &server->tcp_ses_list); |
1699 | spin_unlock(lock: &cifs_tcp_ses_lock); |
1700 | |
1701 | cancel_delayed_work_sync(dwork: &server->echo); |
1702 | |
1703 | if (from_reconnect) |
1704 | /* |
1705 | * Avoid deadlock here: reconnect work calls |
1706 | * cifs_put_tcp_session() at its end. Need to be sure |
1707 | * that reconnect work does nothing with server pointer after |
1708 | * that step. |
1709 | */ |
1710 | cancel_delayed_work(dwork: &server->reconnect); |
1711 | else |
1712 | cancel_delayed_work_sync(dwork: &server->reconnect); |
1713 | |
1714 | /* For secondary channels, we pick up ref-count on the primary server */ |
1715 | if (SERVER_IS_CHAN(server)) |
1716 | cifs_put_tcp_session(server: server->primary_server, from_reconnect); |
1717 | |
1718 | spin_lock(lock: &server->srv_lock); |
1719 | server->tcpStatus = CifsExiting; |
1720 | spin_unlock(lock: &server->srv_lock); |
1721 | |
1722 | cifs_crypto_secmech_release(server); |
1723 | |
1724 | kfree_sensitive(objp: server->session_key.response); |
1725 | server->session_key.response = NULL; |
1726 | server->session_key.len = 0; |
1727 | |
1728 | task = xchg(&server->tsk, NULL); |
1729 | if (task) |
1730 | send_sig(SIGKILL, task, 1); |
1731 | } |
1732 | |
1733 | struct TCP_Server_Info * |
1734 | cifs_get_tcp_session(struct smb3_fs_context *ctx, |
1735 | struct TCP_Server_Info *primary_server) |
1736 | { |
1737 | struct TCP_Server_Info *tcp_ses = NULL; |
1738 | int rc; |
1739 | |
1740 | cifs_dbg(FYI, "UNC: %s\n" , ctx->UNC); |
1741 | |
1742 | /* see if we already have a matching tcp_ses */ |
1743 | tcp_ses = cifs_find_tcp_session(ctx); |
1744 | if (tcp_ses) |
1745 | return tcp_ses; |
1746 | |
1747 | tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); |
1748 | if (!tcp_ses) { |
1749 | rc = -ENOMEM; |
1750 | goto out_err; |
1751 | } |
1752 | |
1753 | tcp_ses->hostname = kstrdup(s: ctx->server_hostname, GFP_KERNEL); |
1754 | if (!tcp_ses->hostname) { |
1755 | rc = -ENOMEM; |
1756 | goto out_err; |
1757 | } |
1758 | |
1759 | if (ctx->leaf_fullpath) { |
1760 | tcp_ses->leaf_fullpath = kstrdup(s: ctx->leaf_fullpath, GFP_KERNEL); |
1761 | if (!tcp_ses->leaf_fullpath) { |
1762 | rc = -ENOMEM; |
1763 | goto out_err; |
1764 | } |
1765 | } |
1766 | if (ctx->dns_dom) |
1767 | strscpy(tcp_ses->dns_dom, ctx->dns_dom); |
1768 | |
1769 | if (ctx->nosharesock) |
1770 | tcp_ses->nosharesock = true; |
1771 | tcp_ses->dfs_conn = ctx->dfs_conn; |
1772 | |
1773 | tcp_ses->ops = ctx->ops; |
1774 | tcp_ses->vals = ctx->vals; |
1775 | cifs_set_net_ns(srv: tcp_ses, net: get_net(current->nsproxy->net_ns)); |
1776 | |
1777 | tcp_ses->sign = ctx->sign; |
1778 | tcp_ses->conn_id = atomic_inc_return(v: &tcpSesNextId); |
1779 | tcp_ses->noblockcnt = ctx->rootfs; |
1780 | tcp_ses->noblocksnd = ctx->noblocksnd || ctx->rootfs; |
1781 | tcp_ses->noautotune = ctx->noautotune; |
1782 | tcp_ses->tcp_nodelay = ctx->sockopt_tcp_nodelay; |
1783 | tcp_ses->rdma = ctx->rdma; |
1784 | tcp_ses->in_flight = 0; |
1785 | tcp_ses->max_in_flight = 0; |
1786 | tcp_ses->credits = 1; |
1787 | if (primary_server) { |
1788 | spin_lock(lock: &cifs_tcp_ses_lock); |
1789 | ++primary_server->srv_count; |
1790 | spin_unlock(lock: &cifs_tcp_ses_lock); |
1791 | tcp_ses->primary_server = primary_server; |
1792 | } |
1793 | init_waitqueue_head(&tcp_ses->response_q); |
1794 | init_waitqueue_head(&tcp_ses->request_q); |
1795 | INIT_LIST_HEAD(list: &tcp_ses->pending_mid_q); |
1796 | mutex_init(&tcp_ses->_srv_mutex); |
1797 | memcpy(tcp_ses->workstation_RFC1001_name, |
1798 | ctx->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); |
1799 | memcpy(tcp_ses->server_RFC1001_name, |
1800 | ctx->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); |
1801 | tcp_ses->rfc1001_sessinit = ctx->rfc1001_sessinit; |
1802 | tcp_ses->with_rfc1001 = false; |
1803 | tcp_ses->session_estab = false; |
1804 | tcp_ses->sequence_number = 0; |
1805 | tcp_ses->channel_sequence_num = 0; /* only tracked for primary channel */ |
1806 | tcp_ses->reconnect_instance = 1; |
1807 | tcp_ses->lstrp = jiffies; |
1808 | tcp_ses->compression.requested = ctx->compress; |
1809 | spin_lock_init(&tcp_ses->req_lock); |
1810 | spin_lock_init(&tcp_ses->srv_lock); |
1811 | spin_lock_init(&tcp_ses->mid_lock); |
1812 | INIT_LIST_HEAD(list: &tcp_ses->tcp_ses_list); |
1813 | INIT_LIST_HEAD(list: &tcp_ses->smb_ses_list); |
1814 | INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); |
1815 | INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server); |
1816 | mutex_init(&tcp_ses->reconnect_mutex); |
1817 | memcpy(&tcp_ses->srcaddr, &ctx->srcaddr, |
1818 | sizeof(tcp_ses->srcaddr)); |
1819 | memcpy(&tcp_ses->dstaddr, &ctx->dstaddr, |
1820 | sizeof(tcp_ses->dstaddr)); |
1821 | if (ctx->use_client_guid) |
1822 | memcpy(tcp_ses->client_guid, ctx->client_guid, |
1823 | SMB2_CLIENT_GUID_SIZE); |
1824 | else |
1825 | generate_random_uuid(uuid: tcp_ses->client_guid); |
1826 | /* |
1827 | * at this point we are the only ones with the pointer |
1828 | * to the struct since the kernel thread not created yet |
1829 | * no need to spinlock this init of tcpStatus or srv_count |
1830 | */ |
1831 | tcp_ses->tcpStatus = CifsNew; |
1832 | ++tcp_ses->srv_count; |
1833 | tcp_ses->echo_interval = ctx->echo_interval * HZ; |
1834 | |
1835 | if (tcp_ses->rdma) { |
1836 | #ifndef CONFIG_CIFS_SMB_DIRECT |
1837 | cifs_dbg(VFS, "CONFIG_CIFS_SMB_DIRECT is not enabled\n" ); |
1838 | rc = -ENOENT; |
1839 | goto out_err_crypto_release; |
1840 | #endif |
1841 | tcp_ses->smbd_conn = smbd_get_connection( |
1842 | server: tcp_ses, dstaddr: (struct sockaddr *)&ctx->dstaddr); |
1843 | if (tcp_ses->smbd_conn) { |
1844 | cifs_dbg(VFS, "RDMA transport established\n" ); |
1845 | rc = 0; |
1846 | goto smbd_connected; |
1847 | } else { |
1848 | rc = -ENOENT; |
1849 | goto out_err_crypto_release; |
1850 | } |
1851 | } |
1852 | rc = ip_connect(server: tcp_ses); |
1853 | if (rc < 0) { |
1854 | cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n" ); |
1855 | goto out_err_crypto_release; |
1856 | } |
1857 | smbd_connected: |
1858 | /* |
1859 | * since we're in a cifs function already, we know that |
1860 | * this will succeed. No need for try_module_get(). |
1861 | */ |
1862 | __module_get(THIS_MODULE); |
1863 | tcp_ses->tsk = kthread_run(cifs_demultiplex_thread, |
1864 | tcp_ses, "cifsd" ); |
1865 | if (IS_ERR(ptr: tcp_ses->tsk)) { |
1866 | rc = PTR_ERR(ptr: tcp_ses->tsk); |
1867 | cifs_dbg(VFS, "error %d create cifsd thread\n" , rc); |
1868 | module_put(THIS_MODULE); |
1869 | goto out_err_crypto_release; |
1870 | } |
1871 | tcp_ses->min_offload = ctx->min_offload; |
1872 | tcp_ses->retrans = ctx->retrans; |
1873 | /* |
1874 | * at this point we are the only ones with the pointer |
1875 | * to the struct since the kernel thread not created yet |
1876 | * no need to spinlock this update of tcpStatus |
1877 | */ |
1878 | spin_lock(lock: &tcp_ses->srv_lock); |
1879 | tcp_ses->tcpStatus = CifsNeedNegotiate; |
1880 | spin_unlock(lock: &tcp_ses->srv_lock); |
1881 | |
1882 | if ((ctx->max_credits < 20) || (ctx->max_credits > 60000)) |
1883 | tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE; |
1884 | else |
1885 | tcp_ses->max_credits = ctx->max_credits; |
1886 | |
1887 | tcp_ses->nr_targets = 1; |
1888 | tcp_ses->ignore_signature = ctx->ignore_signature; |
1889 | /* thread spawned, put it on the list */ |
1890 | spin_lock(lock: &cifs_tcp_ses_lock); |
1891 | list_add(new: &tcp_ses->tcp_ses_list, head: &cifs_tcp_ses_list); |
1892 | spin_unlock(lock: &cifs_tcp_ses_lock); |
1893 | |
1894 | /* queue echo request delayed work */ |
1895 | queue_delayed_work(wq: cifsiod_wq, dwork: &tcp_ses->echo, delay: tcp_ses->echo_interval); |
1896 | |
1897 | return tcp_ses; |
1898 | |
1899 | out_err_crypto_release: |
1900 | cifs_crypto_secmech_release(server: tcp_ses); |
1901 | |
1902 | put_net(net: cifs_net_ns(srv: tcp_ses)); |
1903 | |
1904 | out_err: |
1905 | if (tcp_ses) { |
1906 | if (SERVER_IS_CHAN(tcp_ses)) |
1907 | cifs_put_tcp_session(server: tcp_ses->primary_server, from_reconnect: false); |
1908 | kfree(objp: tcp_ses->hostname); |
1909 | kfree(objp: tcp_ses->leaf_fullpath); |
1910 | if (tcp_ses->ssocket) |
1911 | sock_release(sock: tcp_ses->ssocket); |
1912 | kfree(objp: tcp_ses); |
1913 | } |
1914 | return ERR_PTR(error: rc); |
1915 | } |
1916 | |
1917 | /* this function must be called with ses_lock and chan_lock held */ |
1918 | static int match_session(struct cifs_ses *ses, |
1919 | struct smb3_fs_context *ctx, |
1920 | bool match_super) |
1921 | { |
1922 | struct TCP_Server_Info *server = ses->server; |
1923 | enum securityEnum ctx_sec, ses_sec; |
1924 | |
1925 | if (!match_super && ctx->dfs_root_ses != ses->dfs_root_ses) |
1926 | return 0; |
1927 | |
1928 | /* |
1929 | * If an existing session is limited to less channels than |
1930 | * requested, it should not be reused |
1931 | */ |
1932 | if (ses->chan_max < ctx->max_channels) |
1933 | return 0; |
1934 | |
1935 | ctx_sec = server->ops->select_sectype(server, ctx->sectype); |
1936 | ses_sec = server->ops->select_sectype(server, ses->sectype); |
1937 | |
1938 | if (ctx_sec != ses_sec) |
1939 | return 0; |
1940 | |
1941 | switch (ctx_sec) { |
1942 | case IAKerb: |
1943 | case Kerberos: |
1944 | if (!uid_eq(left: ctx->cred_uid, right: ses->cred_uid)) |
1945 | return 0; |
1946 | break; |
1947 | case NTLMv2: |
1948 | case RawNTLMSSP: |
1949 | default: |
1950 | /* NULL username means anonymous session */ |
1951 | if (ses->user_name == NULL) { |
1952 | if (!ctx->nullauth) |
1953 | return 0; |
1954 | break; |
1955 | } |
1956 | |
1957 | /* anything else takes username/password */ |
1958 | if (strncmp(ses->user_name, |
1959 | ctx->username ? ctx->username : "" , |
1960 | CIFS_MAX_USERNAME_LEN)) |
1961 | return 0; |
1962 | if ((ctx->username && strlen(ctx->username) != 0) && |
1963 | ses->password != NULL) { |
1964 | |
1965 | /* New mount can only share sessions with an existing mount if: |
1966 | * 1. Both password and password2 match, or |
1967 | * 2. password2 of the old mount matches password of the new mount |
1968 | * and password of the old mount matches password2 of the new |
1969 | * mount |
1970 | */ |
1971 | if (ses->password2 != NULL && ctx->password2 != NULL) { |
1972 | if (!((strncmp(ses->password, ctx->password ? |
1973 | ctx->password : "" , CIFS_MAX_PASSWORD_LEN) == 0 && |
1974 | strncmp(ses->password2, ctx->password2, |
1975 | CIFS_MAX_PASSWORD_LEN) == 0) || |
1976 | (strncmp(ses->password, ctx->password2, |
1977 | CIFS_MAX_PASSWORD_LEN) == 0 && |
1978 | strncmp(ses->password2, ctx->password ? |
1979 | ctx->password : "" , CIFS_MAX_PASSWORD_LEN) == 0))) |
1980 | return 0; |
1981 | |
1982 | } else if ((ses->password2 == NULL && ctx->password2 != NULL) || |
1983 | (ses->password2 != NULL && ctx->password2 == NULL)) { |
1984 | return 0; |
1985 | |
1986 | } else { |
1987 | if (strncmp(ses->password, ctx->password ? |
1988 | ctx->password : "" , CIFS_MAX_PASSWORD_LEN)) |
1989 | return 0; |
1990 | } |
1991 | } |
1992 | } |
1993 | |
1994 | if (strcmp(ctx->local_nls->charset, ses->local_nls->charset)) |
1995 | return 0; |
1996 | |
1997 | return 1; |
1998 | } |
1999 | |
2000 | /** |
2001 | * cifs_setup_ipc - helper to setup the IPC tcon for the session |
2002 | * @ses: smb session to issue the request on |
2003 | * @ctx: the superblock configuration context to use for building the |
2004 | * new tree connection for the IPC (interprocess communication RPC) |
2005 | * |
2006 | * A new IPC connection is made and stored in the session |
2007 | * tcon_ipc. The IPC tcon has the same lifetime as the session. |
2008 | */ |
2009 | static int |
2010 | cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx) |
2011 | { |
2012 | int rc = 0, xid; |
2013 | struct cifs_tcon *tcon; |
2014 | char unc[SERVER_NAME_LENGTH + sizeof("//x/IPC$" )] = {0}; |
2015 | bool seal = false; |
2016 | struct TCP_Server_Info *server = ses->server; |
2017 | |
2018 | /* |
2019 | * If the mount request that resulted in the creation of the |
2020 | * session requires encryption, force IPC to be encrypted too. |
2021 | */ |
2022 | if (ctx->seal) { |
2023 | if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) |
2024 | seal = true; |
2025 | else { |
2026 | cifs_server_dbg(VFS, |
2027 | "IPC: server doesn't support encryption\n" ); |
2028 | return -EOPNOTSUPP; |
2029 | } |
2030 | } |
2031 | |
2032 | /* no need to setup directory caching on IPC share, so pass in false */ |
2033 | tcon = tcon_info_alloc(dir_leases_enabled: false, trace: netfs_trace_tcon_ref_new_ipc); |
2034 | if (tcon == NULL) |
2035 | return -ENOMEM; |
2036 | |
2037 | spin_lock(lock: &server->srv_lock); |
2038 | scnprintf(buf: unc, size: sizeof(unc), fmt: "\\\\%s\\IPC$" , server->hostname); |
2039 | spin_unlock(lock: &server->srv_lock); |
2040 | |
2041 | xid = get_xid(); |
2042 | tcon->ses = ses; |
2043 | tcon->ipc = true; |
2044 | tcon->seal = seal; |
2045 | rc = server->ops->tree_connect(xid, ses, unc, tcon, ctx->local_nls); |
2046 | free_xid(xid); |
2047 | |
2048 | if (rc) { |
2049 | cifs_server_dbg(VFS, "failed to connect to IPC (rc=%d)\n" , rc); |
2050 | tconInfoFree(tcon, trace: netfs_trace_tcon_ref_free_ipc_fail); |
2051 | goto out; |
2052 | } |
2053 | |
2054 | cifs_dbg(FYI, "IPC tcon rc=%d ipc tid=0x%x\n" , rc, tcon->tid); |
2055 | |
2056 | spin_lock(lock: &tcon->tc_lock); |
2057 | tcon->status = TID_GOOD; |
2058 | spin_unlock(lock: &tcon->tc_lock); |
2059 | ses->tcon_ipc = tcon; |
2060 | out: |
2061 | return rc; |
2062 | } |
2063 | |
2064 | static struct cifs_ses * |
2065 | cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) |
2066 | { |
2067 | struct cifs_ses *ses, *ret = NULL; |
2068 | |
2069 | spin_lock(lock: &cifs_tcp_ses_lock); |
2070 | list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { |
2071 | spin_lock(lock: &ses->ses_lock); |
2072 | if (ses->ses_status == SES_EXITING) { |
2073 | spin_unlock(lock: &ses->ses_lock); |
2074 | continue; |
2075 | } |
2076 | spin_lock(lock: &ses->chan_lock); |
2077 | if (match_session(ses, ctx, match_super: false)) { |
2078 | spin_unlock(lock: &ses->chan_lock); |
2079 | spin_unlock(lock: &ses->ses_lock); |
2080 | ret = ses; |
2081 | break; |
2082 | } |
2083 | spin_unlock(lock: &ses->chan_lock); |
2084 | spin_unlock(lock: &ses->ses_lock); |
2085 | } |
2086 | if (ret) |
2087 | cifs_smb_ses_inc_refcount(ses: ret); |
2088 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2089 | return ret; |
2090 | } |
2091 | |
2092 | void __cifs_put_smb_ses(struct cifs_ses *ses) |
2093 | { |
2094 | struct TCP_Server_Info *server = ses->server; |
2095 | struct cifs_tcon *tcon; |
2096 | unsigned int xid; |
2097 | size_t i; |
2098 | bool do_logoff; |
2099 | int rc; |
2100 | |
2101 | spin_lock(lock: &cifs_tcp_ses_lock); |
2102 | spin_lock(lock: &ses->ses_lock); |
2103 | cifs_dbg(FYI, "%s: id=0x%llx ses_count=%d ses_status=%u ipc=%s\n" , |
2104 | __func__, ses->Suid, ses->ses_count, ses->ses_status, |
2105 | ses->tcon_ipc ? ses->tcon_ipc->tree_name : "none" ); |
2106 | if (ses->ses_status == SES_EXITING || --ses->ses_count > 0) { |
2107 | spin_unlock(lock: &ses->ses_lock); |
2108 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2109 | return; |
2110 | } |
2111 | /* ses_count can never go negative */ |
2112 | WARN_ON(ses->ses_count < 0); |
2113 | |
2114 | spin_lock(lock: &ses->chan_lock); |
2115 | cifs_chan_clear_need_reconnect(ses, server); |
2116 | spin_unlock(lock: &ses->chan_lock); |
2117 | |
2118 | do_logoff = ses->ses_status == SES_GOOD && server->ops->logoff; |
2119 | ses->ses_status = SES_EXITING; |
2120 | tcon = ses->tcon_ipc; |
2121 | ses->tcon_ipc = NULL; |
2122 | spin_unlock(lock: &ses->ses_lock); |
2123 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2124 | |
2125 | /* |
2126 | * On session close, the IPC is closed and the server must release all |
2127 | * tcons of the session. No need to send a tree disconnect here. |
2128 | * |
2129 | * Besides, it will make the server to not close durable and resilient |
2130 | * files on session close, as specified in MS-SMB2 3.3.5.6 Receiving an |
2131 | * SMB2 LOGOFF Request. |
2132 | */ |
2133 | tconInfoFree(tcon, trace: netfs_trace_tcon_ref_free_ipc); |
2134 | if (do_logoff) { |
2135 | xid = get_xid(); |
2136 | rc = server->ops->logoff(xid, ses); |
2137 | cifs_server_dbg(FYI, "%s: Session Logoff: rc=%d\n" , |
2138 | __func__, rc); |
2139 | _free_xid(xid); |
2140 | } |
2141 | |
2142 | spin_lock(lock: &cifs_tcp_ses_lock); |
2143 | list_del_init(entry: &ses->smb_ses_list); |
2144 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2145 | |
2146 | /* close any extra channels */ |
2147 | for (i = 1; i < ses->chan_count; i++) { |
2148 | if (ses->chans[i].iface) { |
2149 | kref_put(kref: &ses->chans[i].iface->refcount, release: release_iface); |
2150 | ses->chans[i].iface = NULL; |
2151 | } |
2152 | cifs_put_tcp_session(server: ses->chans[i].server, from_reconnect: 0); |
2153 | ses->chans[i].server = NULL; |
2154 | } |
2155 | |
2156 | /* we now account for primary channel in iface->refcount */ |
2157 | if (ses->chans[0].iface) { |
2158 | kref_put(kref: &ses->chans[0].iface->refcount, release: release_iface); |
2159 | ses->chans[0].server = NULL; |
2160 | } |
2161 | |
2162 | sesInfoFree(ses); |
2163 | cifs_put_tcp_session(server, from_reconnect: 0); |
2164 | } |
2165 | |
2166 | #ifdef CONFIG_KEYS |
2167 | |
2168 | /* strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1 */ |
2169 | #define CIFSCREDS_DESC_SIZE (7 + CIFS_MAX_DOMAINNAME_LEN + 1) |
2170 | |
2171 | /* Populate username and pw fields from keyring if possible */ |
2172 | static int |
2173 | cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) |
2174 | { |
2175 | int rc = 0; |
2176 | int is_domain = 0; |
2177 | const char *delim, *payload; |
2178 | char *desc; |
2179 | ssize_t len; |
2180 | struct key *key; |
2181 | struct TCP_Server_Info *server = ses->server; |
2182 | struct sockaddr_in *sa; |
2183 | struct sockaddr_in6 *sa6; |
2184 | const struct user_key_payload *upayload; |
2185 | |
2186 | desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL); |
2187 | if (!desc) |
2188 | return -ENOMEM; |
2189 | |
2190 | /* try to find an address key first */ |
2191 | switch (server->dstaddr.ss_family) { |
2192 | case AF_INET: |
2193 | sa = (struct sockaddr_in *)&server->dstaddr; |
2194 | sprintf(buf: desc, fmt: "cifs:a:%pI4" , &sa->sin_addr.s_addr); |
2195 | break; |
2196 | case AF_INET6: |
2197 | sa6 = (struct sockaddr_in6 *)&server->dstaddr; |
2198 | sprintf(buf: desc, fmt: "cifs:a:%pI6c" , &sa6->sin6_addr.s6_addr); |
2199 | break; |
2200 | default: |
2201 | cifs_dbg(FYI, "Bad ss_family (%hu)\n" , |
2202 | server->dstaddr.ss_family); |
2203 | rc = -EINVAL; |
2204 | goto out_err; |
2205 | } |
2206 | |
2207 | cifs_dbg(FYI, "%s: desc=%s\n" , __func__, desc); |
2208 | key = request_key(type: &key_type_logon, description: desc, callout_info: "" ); |
2209 | if (IS_ERR(ptr: key)) { |
2210 | if (!ses->domainName) { |
2211 | cifs_dbg(FYI, "domainName is NULL\n" ); |
2212 | rc = PTR_ERR(ptr: key); |
2213 | goto out_err; |
2214 | } |
2215 | |
2216 | /* didn't work, try to find a domain key */ |
2217 | sprintf(buf: desc, fmt: "cifs:d:%s" , ses->domainName); |
2218 | cifs_dbg(FYI, "%s: desc=%s\n" , __func__, desc); |
2219 | key = request_key(type: &key_type_logon, description: desc, callout_info: "" ); |
2220 | if (IS_ERR(ptr: key)) { |
2221 | rc = PTR_ERR(ptr: key); |
2222 | goto out_err; |
2223 | } |
2224 | is_domain = 1; |
2225 | } |
2226 | |
2227 | down_read(sem: &key->sem); |
2228 | upayload = user_key_payload_locked(key); |
2229 | if (IS_ERR_OR_NULL(ptr: upayload)) { |
2230 | rc = upayload ? PTR_ERR(ptr: upayload) : -EINVAL; |
2231 | goto out_key_put; |
2232 | } |
2233 | |
2234 | /* find first : in payload */ |
2235 | payload = upayload->data; |
2236 | delim = strnchr(payload, upayload->datalen, ':'); |
2237 | cifs_dbg(FYI, "payload=%s\n" , payload); |
2238 | if (!delim) { |
2239 | cifs_dbg(FYI, "Unable to find ':' in payload (datalen=%d)\n" , |
2240 | upayload->datalen); |
2241 | rc = -EINVAL; |
2242 | goto out_key_put; |
2243 | } |
2244 | |
2245 | len = delim - payload; |
2246 | if (len > CIFS_MAX_USERNAME_LEN || len <= 0) { |
2247 | cifs_dbg(FYI, "Bad value from username search (len=%zd)\n" , |
2248 | len); |
2249 | rc = -EINVAL; |
2250 | goto out_key_put; |
2251 | } |
2252 | |
2253 | ctx->username = kstrndup(s: payload, len, GFP_KERNEL); |
2254 | if (!ctx->username) { |
2255 | cifs_dbg(FYI, "Unable to allocate %zd bytes for username\n" , |
2256 | len); |
2257 | rc = -ENOMEM; |
2258 | goto out_key_put; |
2259 | } |
2260 | cifs_dbg(FYI, "%s: username=%s\n" , __func__, ctx->username); |
2261 | |
2262 | len = key->datalen - (len + 1); |
2263 | if (len > CIFS_MAX_PASSWORD_LEN || len <= 0) { |
2264 | cifs_dbg(FYI, "Bad len for password search (len=%zd)\n" , len); |
2265 | rc = -EINVAL; |
2266 | kfree(objp: ctx->username); |
2267 | ctx->username = NULL; |
2268 | goto out_key_put; |
2269 | } |
2270 | |
2271 | ++delim; |
2272 | /* BB consider adding support for password2 (Key Rotation) for multiuser in future */ |
2273 | ctx->password = kstrndup(s: delim, len, GFP_KERNEL); |
2274 | if (!ctx->password) { |
2275 | cifs_dbg(FYI, "Unable to allocate %zd bytes for password\n" , |
2276 | len); |
2277 | rc = -ENOMEM; |
2278 | kfree(objp: ctx->username); |
2279 | ctx->username = NULL; |
2280 | goto out_key_put; |
2281 | } |
2282 | |
2283 | /* |
2284 | * If we have a domain key then we must set the domainName in the |
2285 | * for the request. |
2286 | */ |
2287 | if (is_domain && ses->domainName) { |
2288 | ctx->domainname = kstrdup(s: ses->domainName, GFP_KERNEL); |
2289 | if (!ctx->domainname) { |
2290 | cifs_dbg(FYI, "Unable to allocate %zd bytes for domain\n" , |
2291 | len); |
2292 | rc = -ENOMEM; |
2293 | kfree(objp: ctx->username); |
2294 | ctx->username = NULL; |
2295 | kfree_sensitive(objp: ctx->password); |
2296 | /* no need to free ctx->password2 since not allocated in this path */ |
2297 | ctx->password = NULL; |
2298 | goto out_key_put; |
2299 | } |
2300 | } |
2301 | |
2302 | strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name)); |
2303 | |
2304 | out_key_put: |
2305 | up_read(sem: &key->sem); |
2306 | key_put(key); |
2307 | out_err: |
2308 | kfree(objp: desc); |
2309 | cifs_dbg(FYI, "%s: returning %d\n" , __func__, rc); |
2310 | return rc; |
2311 | } |
2312 | #else /* ! CONFIG_KEYS */ |
2313 | static inline int |
2314 | cifs_set_cifscreds(struct smb3_fs_context *ctx __attribute__((unused)), |
2315 | struct cifs_ses *ses __attribute__((unused))) |
2316 | { |
2317 | return -ENOSYS; |
2318 | } |
2319 | #endif /* CONFIG_KEYS */ |
2320 | |
2321 | /** |
2322 | * cifs_get_smb_ses - get a session matching @ctx data from @server |
2323 | * @server: server to setup the session to |
2324 | * @ctx: superblock configuration context to use to setup the session |
2325 | * |
2326 | * This function assumes it is being called from cifs_mount() where we |
2327 | * already got a server reference (server refcount +1). See |
2328 | * cifs_get_tcon() for refcount explanations. |
2329 | */ |
2330 | struct cifs_ses * |
2331 | cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) |
2332 | { |
2333 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; |
2334 | struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; |
2335 | struct cifs_ses *ses; |
2336 | unsigned int xid; |
2337 | int retries = 0; |
2338 | size_t len; |
2339 | int rc = 0; |
2340 | |
2341 | xid = get_xid(); |
2342 | |
2343 | ses = cifs_find_smb_ses(server, ctx); |
2344 | if (ses) { |
2345 | cifs_dbg(FYI, "Existing smb sess found (status=%d)\n" , |
2346 | ses->ses_status); |
2347 | |
2348 | spin_lock(lock: &ses->chan_lock); |
2349 | if (cifs_chan_needs_reconnect(ses, server)) { |
2350 | spin_unlock(lock: &ses->chan_lock); |
2351 | cifs_dbg(FYI, "Session needs reconnect\n" ); |
2352 | |
2353 | mutex_lock(&ses->session_mutex); |
2354 | |
2355 | retry_old_session: |
2356 | rc = cifs_negotiate_protocol(xid, ses, server); |
2357 | if (rc) { |
2358 | mutex_unlock(lock: &ses->session_mutex); |
2359 | /* problem -- put our ses reference */ |
2360 | cifs_put_smb_ses(ses); |
2361 | free_xid(xid); |
2362 | return ERR_PTR(error: rc); |
2363 | } |
2364 | |
2365 | rc = cifs_setup_session(xid, ses, server, |
2366 | nls_info: ctx->local_nls); |
2367 | if (rc) { |
2368 | if (((rc == -EACCES) || (rc == -EKEYEXPIRED) || |
2369 | (rc == -EKEYREVOKED)) && !retries && ses->password2) { |
2370 | retries++; |
2371 | cifs_dbg(FYI, "Session reconnect failed, retrying with alternate password\n" ); |
2372 | swap(ses->password, ses->password2); |
2373 | goto retry_old_session; |
2374 | } |
2375 | mutex_unlock(lock: &ses->session_mutex); |
2376 | /* problem -- put our reference */ |
2377 | cifs_put_smb_ses(ses); |
2378 | free_xid(xid); |
2379 | return ERR_PTR(error: rc); |
2380 | } |
2381 | mutex_unlock(lock: &ses->session_mutex); |
2382 | |
2383 | spin_lock(lock: &ses->chan_lock); |
2384 | } |
2385 | spin_unlock(lock: &ses->chan_lock); |
2386 | |
2387 | /* existing SMB ses has a server reference already */ |
2388 | cifs_put_tcp_session(server, from_reconnect: 0); |
2389 | free_xid(xid); |
2390 | return ses; |
2391 | } |
2392 | |
2393 | rc = -ENOMEM; |
2394 | |
2395 | cifs_dbg(FYI, "Existing smb sess not found\n" ); |
2396 | ses = sesInfoAlloc(); |
2397 | if (ses == NULL) |
2398 | goto get_ses_fail; |
2399 | |
2400 | /* new SMB session uses our server ref */ |
2401 | ses->server = server; |
2402 | if (server->dstaddr.ss_family == AF_INET6) |
2403 | sprintf(buf: ses->ip_addr, fmt: "%pI6" , &addr6->sin6_addr); |
2404 | else |
2405 | sprintf(buf: ses->ip_addr, fmt: "%pI4" , &addr->sin_addr); |
2406 | |
2407 | if (ctx->username) { |
2408 | ses->user_name = kstrdup(s: ctx->username, GFP_KERNEL); |
2409 | if (!ses->user_name) |
2410 | goto get_ses_fail; |
2411 | } |
2412 | |
2413 | /* ctx->password freed at unmount */ |
2414 | if (ctx->password) { |
2415 | ses->password = kstrdup(s: ctx->password, GFP_KERNEL); |
2416 | if (!ses->password) |
2417 | goto get_ses_fail; |
2418 | } |
2419 | /* ctx->password freed at unmount */ |
2420 | if (ctx->password2) { |
2421 | ses->password2 = kstrdup(s: ctx->password2, GFP_KERNEL); |
2422 | if (!ses->password2) |
2423 | goto get_ses_fail; |
2424 | } |
2425 | if (ctx->domainname) { |
2426 | ses->domainName = kstrdup(s: ctx->domainname, GFP_KERNEL); |
2427 | if (!ses->domainName) |
2428 | goto get_ses_fail; |
2429 | |
2430 | len = strnlen(p: ctx->domainname, CIFS_MAX_DOMAINNAME_LEN); |
2431 | if (!cifs_netbios_name(name: ctx->domainname, namelen: len)) { |
2432 | ses->dns_dom = kstrndup(s: ctx->domainname, |
2433 | len, GFP_KERNEL); |
2434 | if (!ses->dns_dom) |
2435 | goto get_ses_fail; |
2436 | } |
2437 | } |
2438 | |
2439 | strscpy(ses->workstation_name, ctx->workstation_name, sizeof(ses->workstation_name)); |
2440 | |
2441 | if (ctx->domainauto) |
2442 | ses->domainAuto = ctx->domainauto; |
2443 | ses->cred_uid = ctx->cred_uid; |
2444 | ses->linux_uid = ctx->linux_uid; |
2445 | |
2446 | ses->unicode = ctx->unicode; |
2447 | ses->sectype = ctx->sectype; |
2448 | ses->sign = ctx->sign; |
2449 | |
2450 | /* |
2451 | *Explicitly marking upcall_target mount option for easier handling |
2452 | * by cifs_spnego.c and eventually cifs.upcall.c |
2453 | */ |
2454 | |
2455 | switch (ctx->upcall_target) { |
2456 | case UPTARGET_UNSPECIFIED: /* default to app */ |
2457 | case UPTARGET_APP: |
2458 | ses->upcall_target = UPTARGET_APP; |
2459 | break; |
2460 | case UPTARGET_MOUNT: |
2461 | ses->upcall_target = UPTARGET_MOUNT; |
2462 | break; |
2463 | default: |
2464 | // should never happen |
2465 | ses->upcall_target = UPTARGET_APP; |
2466 | break; |
2467 | } |
2468 | |
2469 | ses->local_nls = load_nls(charset: ctx->local_nls->charset); |
2470 | |
2471 | /* add server as first channel */ |
2472 | spin_lock(lock: &ses->chan_lock); |
2473 | ses->chans[0].server = server; |
2474 | ses->chan_count = 1; |
2475 | ses->chan_max = ctx->multichannel ? ctx->max_channels:1; |
2476 | ses->chans_need_reconnect = 1; |
2477 | spin_unlock(lock: &ses->chan_lock); |
2478 | |
2479 | retry_new_session: |
2480 | mutex_lock(&ses->session_mutex); |
2481 | rc = cifs_negotiate_protocol(xid, ses, server); |
2482 | if (!rc) |
2483 | rc = cifs_setup_session(xid, ses, server, nls_info: ctx->local_nls); |
2484 | mutex_unlock(lock: &ses->session_mutex); |
2485 | |
2486 | /* each channel uses a different signing key */ |
2487 | spin_lock(lock: &ses->chan_lock); |
2488 | memcpy(ses->chans[0].signkey, ses->smb3signingkey, |
2489 | sizeof(ses->smb3signingkey)); |
2490 | spin_unlock(lock: &ses->chan_lock); |
2491 | |
2492 | if (rc) { |
2493 | if (((rc == -EACCES) || (rc == -EKEYEXPIRED) || |
2494 | (rc == -EKEYREVOKED)) && !retries && ses->password2) { |
2495 | retries++; |
2496 | cifs_dbg(FYI, "Session setup failed, retrying with alternate password\n" ); |
2497 | swap(ses->password, ses->password2); |
2498 | goto retry_new_session; |
2499 | } else |
2500 | goto get_ses_fail; |
2501 | } |
2502 | |
2503 | /* |
2504 | * success, put it on the list and add it as first channel |
2505 | * note: the session becomes active soon after this. So you'll |
2506 | * need to lock before changing something in the session. |
2507 | */ |
2508 | spin_lock(lock: &cifs_tcp_ses_lock); |
2509 | ses->dfs_root_ses = ctx->dfs_root_ses; |
2510 | list_add(new: &ses->smb_ses_list, head: &server->smb_ses_list); |
2511 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2512 | |
2513 | cifs_setup_ipc(ses, ctx); |
2514 | |
2515 | free_xid(xid); |
2516 | |
2517 | return ses; |
2518 | |
2519 | get_ses_fail: |
2520 | sesInfoFree(ses); |
2521 | free_xid(xid); |
2522 | return ERR_PTR(error: rc); |
2523 | } |
2524 | |
2525 | /* this function must be called with tc_lock held */ |
2526 | static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) |
2527 | { |
2528 | struct TCP_Server_Info *server = tcon->ses->server; |
2529 | |
2530 | if (tcon->status == TID_EXITING) |
2531 | return 0; |
2532 | |
2533 | if (tcon->origin_fullpath) { |
2534 | if (!ctx->source || |
2535 | !dfs_src_pathname_equal(s1: ctx->source, |
2536 | s2: tcon->origin_fullpath)) |
2537 | return 0; |
2538 | } else if (!server->leaf_fullpath && |
2539 | strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE)) { |
2540 | return 0; |
2541 | } |
2542 | if (tcon->seal != ctx->seal) |
2543 | return 0; |
2544 | if (tcon->snapshot_time != ctx->snapshot_time) |
2545 | return 0; |
2546 | if (tcon->handle_timeout != ctx->handle_timeout) |
2547 | return 0; |
2548 | if (tcon->no_lease != ctx->no_lease) |
2549 | return 0; |
2550 | if (tcon->nodelete != ctx->nodelete) |
2551 | return 0; |
2552 | if (tcon->posix_extensions != ctx->linux_ext) |
2553 | return 0; |
2554 | return 1; |
2555 | } |
2556 | |
2557 | static struct cifs_tcon * |
2558 | cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) |
2559 | { |
2560 | struct cifs_tcon *tcon; |
2561 | |
2562 | spin_lock(lock: &cifs_tcp_ses_lock); |
2563 | list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { |
2564 | spin_lock(lock: &tcon->tc_lock); |
2565 | if (!match_tcon(tcon, ctx)) { |
2566 | spin_unlock(lock: &tcon->tc_lock); |
2567 | continue; |
2568 | } |
2569 | ++tcon->tc_count; |
2570 | trace_smb3_tcon_ref(tcon_debug_id: tcon->debug_id, ref: tcon->tc_count, |
2571 | trace: netfs_trace_tcon_ref_get_find); |
2572 | spin_unlock(lock: &tcon->tc_lock); |
2573 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2574 | return tcon; |
2575 | } |
2576 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2577 | return NULL; |
2578 | } |
2579 | |
2580 | void |
2581 | cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace) |
2582 | { |
2583 | unsigned int xid; |
2584 | struct cifs_ses *ses; |
2585 | LIST_HEAD(ses_list); |
2586 | |
2587 | /* |
2588 | * IPC tcon share the lifetime of their session and are |
2589 | * destroyed in the session put function |
2590 | */ |
2591 | if (tcon == NULL || tcon->ipc) |
2592 | return; |
2593 | |
2594 | ses = tcon->ses; |
2595 | cifs_dbg(FYI, "%s: tc_count=%d\n" , __func__, tcon->tc_count); |
2596 | spin_lock(lock: &cifs_tcp_ses_lock); |
2597 | spin_lock(lock: &tcon->tc_lock); |
2598 | trace_smb3_tcon_ref(tcon_debug_id: tcon->debug_id, ref: tcon->tc_count - 1, trace); |
2599 | if (--tcon->tc_count > 0) { |
2600 | spin_unlock(lock: &tcon->tc_lock); |
2601 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2602 | return; |
2603 | } |
2604 | |
2605 | /* tc_count can never go negative */ |
2606 | WARN_ON(tcon->tc_count < 0); |
2607 | |
2608 | list_del_init(entry: &tcon->tcon_list); |
2609 | tcon->status = TID_EXITING; |
2610 | spin_unlock(lock: &tcon->tc_lock); |
2611 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2612 | |
2613 | /* cancel polling of interfaces */ |
2614 | cancel_delayed_work_sync(dwork: &tcon->query_interfaces); |
2615 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2616 | cancel_delayed_work_sync(dwork: &tcon->dfs_cache_work); |
2617 | list_replace_init(old: &tcon->dfs_ses_list, new: &ses_list); |
2618 | #endif |
2619 | |
2620 | if (tcon->use_witness) { |
2621 | int rc; |
2622 | |
2623 | rc = cifs_swn_unregister(tcon); |
2624 | if (rc < 0) { |
2625 | cifs_dbg(VFS, "%s: Failed to unregister for witness notifications: %d\n" , |
2626 | __func__, rc); |
2627 | } |
2628 | } |
2629 | |
2630 | xid = get_xid(); |
2631 | if (ses->server->ops->tree_disconnect) |
2632 | ses->server->ops->tree_disconnect(xid, tcon); |
2633 | _free_xid(xid); |
2634 | |
2635 | cifs_fscache_release_super_cookie(tcon); |
2636 | tconInfoFree(tcon, trace: netfs_trace_tcon_ref_free); |
2637 | cifs_put_smb_ses(ses); |
2638 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2639 | dfs_put_root_smb_sessions(head: &ses_list); |
2640 | #endif |
2641 | } |
2642 | |
2643 | /** |
2644 | * cifs_get_tcon - get a tcon matching @ctx data from @ses |
2645 | * @ses: smb session to issue the request on |
2646 | * @ctx: the superblock configuration context to use for building the |
2647 | * |
2648 | * - tcon refcount is the number of mount points using the tcon. |
2649 | * - ses refcount is the number of tcon using the session. |
2650 | * |
2651 | * 1. This function assumes it is being called from cifs_mount() where |
2652 | * we already got a session reference (ses refcount +1). |
2653 | * |
2654 | * 2. Since we're in the context of adding a mount point, the end |
2655 | * result should be either: |
2656 | * |
2657 | * a) a new tcon already allocated with refcount=1 (1 mount point) and |
2658 | * its session refcount incremented (1 new tcon). This +1 was |
2659 | * already done in (1). |
2660 | * |
2661 | * b) an existing tcon with refcount+1 (add a mount point to it) and |
2662 | * identical ses refcount (no new tcon). Because of (1) we need to |
2663 | * decrement the ses refcount. |
2664 | */ |
2665 | static struct cifs_tcon * |
2666 | cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) |
2667 | { |
2668 | struct cifs_tcon *tcon; |
2669 | bool nohandlecache; |
2670 | int rc, xid; |
2671 | |
2672 | tcon = cifs_find_tcon(ses, ctx); |
2673 | if (tcon) { |
2674 | /* |
2675 | * tcon has refcount already incremented but we need to |
2676 | * decrement extra ses reference gotten by caller (case b) |
2677 | */ |
2678 | cifs_dbg(FYI, "Found match on UNC path\n" ); |
2679 | cifs_put_smb_ses(ses); |
2680 | return tcon; |
2681 | } |
2682 | |
2683 | if (!ses->server->ops->tree_connect) { |
2684 | rc = -ENOSYS; |
2685 | goto out_fail; |
2686 | } |
2687 | |
2688 | if (ses->server->dialect >= SMB20_PROT_ID && |
2689 | (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)) |
2690 | nohandlecache = ctx->nohandlecache || !dir_cache_timeout; |
2691 | else |
2692 | nohandlecache = true; |
2693 | tcon = tcon_info_alloc(dir_leases_enabled: !nohandlecache, trace: netfs_trace_tcon_ref_new); |
2694 | if (tcon == NULL) { |
2695 | rc = -ENOMEM; |
2696 | goto out_fail; |
2697 | } |
2698 | tcon->nohandlecache = nohandlecache; |
2699 | |
2700 | if (ctx->snapshot_time) { |
2701 | if (ses->server->vals->protocol_id == 0) { |
2702 | cifs_dbg(VFS, |
2703 | "Use SMB2 or later for snapshot mount option\n" ); |
2704 | rc = -EOPNOTSUPP; |
2705 | goto out_fail; |
2706 | } else |
2707 | tcon->snapshot_time = ctx->snapshot_time; |
2708 | } |
2709 | |
2710 | if (ctx->handle_timeout) { |
2711 | if (ses->server->vals->protocol_id == 0) { |
2712 | cifs_dbg(VFS, |
2713 | "Use SMB2.1 or later for handle timeout option\n" ); |
2714 | rc = -EOPNOTSUPP; |
2715 | goto out_fail; |
2716 | } else |
2717 | tcon->handle_timeout = ctx->handle_timeout; |
2718 | } |
2719 | |
2720 | tcon->ses = ses; |
2721 | if (ctx->password) { |
2722 | tcon->password = kstrdup(s: ctx->password, GFP_KERNEL); |
2723 | if (!tcon->password) { |
2724 | rc = -ENOMEM; |
2725 | goto out_fail; |
2726 | } |
2727 | } |
2728 | |
2729 | if (ctx->seal) { |
2730 | if (ses->server->vals->protocol_id == 0) { |
2731 | cifs_dbg(VFS, |
2732 | "SMB3 or later required for encryption\n" ); |
2733 | rc = -EOPNOTSUPP; |
2734 | goto out_fail; |
2735 | } else if (tcon->ses->server->capabilities & |
2736 | SMB2_GLOBAL_CAP_ENCRYPTION) |
2737 | tcon->seal = true; |
2738 | else { |
2739 | cifs_dbg(VFS, "Encryption is not supported on share\n" ); |
2740 | rc = -EOPNOTSUPP; |
2741 | goto out_fail; |
2742 | } |
2743 | } |
2744 | |
2745 | if (ctx->linux_ext) { |
2746 | if (ses->server->posix_ext_supported) { |
2747 | tcon->posix_extensions = true; |
2748 | pr_warn_once("SMB3.11 POSIX Extensions are experimental\n" ); |
2749 | } else if ((ses->server->vals->protocol_id == SMB311_PROT_ID) || |
2750 | (strcmp(ses->server->vals->version_string, |
2751 | SMB3ANY_VERSION_STRING) == 0) || |
2752 | (strcmp(ses->server->vals->version_string, |
2753 | SMBDEFAULT_VERSION_STRING) == 0)) { |
2754 | cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n" ); |
2755 | rc = -EOPNOTSUPP; |
2756 | goto out_fail; |
2757 | } else if (ses->server->vals->protocol_id == SMB10_PROT_ID) |
2758 | if (cap_unix(ses)) |
2759 | cifs_dbg(FYI, "Unix Extensions requested on SMB1 mount\n" ); |
2760 | else { |
2761 | cifs_dbg(VFS, "SMB1 Unix Extensions not supported by server\n" ); |
2762 | rc = -EOPNOTSUPP; |
2763 | goto out_fail; |
2764 | } else { |
2765 | cifs_dbg(VFS, |
2766 | "Check vers= mount option. SMB3.11 disabled but required for POSIX extensions\n" ); |
2767 | rc = -EOPNOTSUPP; |
2768 | goto out_fail; |
2769 | } |
2770 | } |
2771 | |
2772 | xid = get_xid(); |
2773 | rc = ses->server->ops->tree_connect(xid, ses, ctx->UNC, tcon, |
2774 | ctx->local_nls); |
2775 | free_xid(xid); |
2776 | cifs_dbg(FYI, "Tcon rc = %d\n" , rc); |
2777 | if (rc) |
2778 | goto out_fail; |
2779 | |
2780 | tcon->use_persistent = false; |
2781 | /* check if SMB2 or later, CIFS does not support persistent handles */ |
2782 | if (ctx->persistent) { |
2783 | if (ses->server->vals->protocol_id == 0) { |
2784 | cifs_dbg(VFS, |
2785 | "SMB3 or later required for persistent handles\n" ); |
2786 | rc = -EOPNOTSUPP; |
2787 | goto out_fail; |
2788 | } else if (ses->server->capabilities & |
2789 | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) |
2790 | tcon->use_persistent = true; |
2791 | else /* persistent handles requested but not supported */ { |
2792 | cifs_dbg(VFS, |
2793 | "Persistent handles not supported on share\n" ); |
2794 | rc = -EOPNOTSUPP; |
2795 | goto out_fail; |
2796 | } |
2797 | } else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY) |
2798 | && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) |
2799 | && (ctx->nopersistent == false)) { |
2800 | cifs_dbg(FYI, "enabling persistent handles\n" ); |
2801 | tcon->use_persistent = true; |
2802 | } else if (ctx->resilient) { |
2803 | if (ses->server->vals->protocol_id == 0) { |
2804 | cifs_dbg(VFS, |
2805 | "SMB2.1 or later required for resilient handles\n" ); |
2806 | rc = -EOPNOTSUPP; |
2807 | goto out_fail; |
2808 | } |
2809 | tcon->use_resilient = true; |
2810 | } |
2811 | |
2812 | tcon->use_witness = false; |
2813 | if (IS_ENABLED(CONFIG_CIFS_SWN_UPCALL) && ctx->witness) { |
2814 | if (ses->server->vals->protocol_id >= SMB30_PROT_ID) { |
2815 | if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER) { |
2816 | /* |
2817 | * Set witness in use flag in first place |
2818 | * to retry registration in the echo task |
2819 | */ |
2820 | tcon->use_witness = true; |
2821 | /* And try to register immediately */ |
2822 | rc = cifs_swn_register(tcon); |
2823 | if (rc < 0) { |
2824 | cifs_dbg(VFS, "Failed to register for witness notifications: %d\n" , rc); |
2825 | goto out_fail; |
2826 | } |
2827 | } else { |
2828 | /* TODO: try to extend for non-cluster uses (eg multichannel) */ |
2829 | cifs_dbg(VFS, "witness requested on mount but no CLUSTER capability on share\n" ); |
2830 | rc = -EOPNOTSUPP; |
2831 | goto out_fail; |
2832 | } |
2833 | } else { |
2834 | cifs_dbg(VFS, "SMB3 or later required for witness option\n" ); |
2835 | rc = -EOPNOTSUPP; |
2836 | goto out_fail; |
2837 | } |
2838 | } |
2839 | |
2840 | /* If the user really knows what they are doing they can override */ |
2841 | if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) { |
2842 | if (ctx->cache_ro) |
2843 | cifs_dbg(VFS, "cache=ro requested on mount but NO_CACHING flag set on share\n" ); |
2844 | else if (ctx->cache_rw) |
2845 | cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n" ); |
2846 | } |
2847 | |
2848 | if (ctx->no_lease) { |
2849 | if (ses->server->vals->protocol_id == 0) { |
2850 | cifs_dbg(VFS, |
2851 | "SMB2 or later required for nolease option\n" ); |
2852 | rc = -EOPNOTSUPP; |
2853 | goto out_fail; |
2854 | } else |
2855 | tcon->no_lease = ctx->no_lease; |
2856 | } |
2857 | |
2858 | /* |
2859 | * We can have only one retry value for a connection to a share so for |
2860 | * resources mounted more than once to the same server share the last |
2861 | * value passed in for the retry flag is used. |
2862 | */ |
2863 | tcon->retry = ctx->retry; |
2864 | tcon->nocase = ctx->nocase; |
2865 | tcon->broken_sparse_sup = ctx->no_sparse; |
2866 | tcon->max_cached_dirs = ctx->max_cached_dirs; |
2867 | tcon->nodelete = ctx->nodelete; |
2868 | tcon->local_lease = ctx->local_lease; |
2869 | INIT_LIST_HEAD(list: &tcon->pending_opens); |
2870 | tcon->status = TID_GOOD; |
2871 | |
2872 | INIT_DELAYED_WORK(&tcon->query_interfaces, |
2873 | smb2_query_server_interfaces); |
2874 | if (ses->server->dialect >= SMB30_PROT_ID && |
2875 | (ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) { |
2876 | /* schedule query interfaces poll */ |
2877 | queue_delayed_work(wq: cifsiod_wq, dwork: &tcon->query_interfaces, |
2878 | delay: (SMB_INTERFACE_POLL_INTERVAL * HZ)); |
2879 | } |
2880 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2881 | INIT_DELAYED_WORK(&tcon->dfs_cache_work, dfs_cache_refresh); |
2882 | #endif |
2883 | spin_lock(lock: &cifs_tcp_ses_lock); |
2884 | list_add(new: &tcon->tcon_list, head: &ses->tcon_list); |
2885 | spin_unlock(lock: &cifs_tcp_ses_lock); |
2886 | |
2887 | return tcon; |
2888 | |
2889 | out_fail: |
2890 | tconInfoFree(tcon, trace: netfs_trace_tcon_ref_free_fail); |
2891 | return ERR_PTR(error: rc); |
2892 | } |
2893 | |
2894 | void |
2895 | cifs_put_tlink(struct tcon_link *tlink) |
2896 | { |
2897 | if (!tlink || IS_ERR(ptr: tlink)) |
2898 | return; |
2899 | |
2900 | if (!atomic_dec_and_test(v: &tlink->tl_count) || |
2901 | test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) { |
2902 | tlink->tl_time = jiffies; |
2903 | return; |
2904 | } |
2905 | |
2906 | if (!IS_ERR(ptr: tlink_tcon(tlink))) |
2907 | cifs_put_tcon(tcon: tlink_tcon(tlink), trace: netfs_trace_tcon_ref_put_tlink); |
2908 | kfree(objp: tlink); |
2909 | } |
2910 | |
2911 | static int |
2912 | compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) |
2913 | { |
2914 | struct cifs_sb_info *old = CIFS_SB(sb); |
2915 | struct cifs_sb_info *new = mnt_data->cifs_sb; |
2916 | unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK; |
2917 | unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK; |
2918 | |
2919 | if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK)) |
2920 | return 0; |
2921 | |
2922 | if (old->mnt_cifs_serverino_autodisabled) |
2923 | newflags &= ~CIFS_MOUNT_SERVER_INUM; |
2924 | |
2925 | if (oldflags != newflags) |
2926 | return 0; |
2927 | |
2928 | /* |
2929 | * We want to share sb only if we don't specify an r/wsize or |
2930 | * specified r/wsize is greater than or equal to existing one. |
2931 | */ |
2932 | if (new->ctx->wsize && new->ctx->wsize < old->ctx->wsize) |
2933 | return 0; |
2934 | |
2935 | if (new->ctx->rsize && new->ctx->rsize < old->ctx->rsize) |
2936 | return 0; |
2937 | |
2938 | if (!uid_eq(left: old->ctx->linux_uid, right: new->ctx->linux_uid) || |
2939 | !gid_eq(left: old->ctx->linux_gid, right: new->ctx->linux_gid)) |
2940 | return 0; |
2941 | |
2942 | if (old->ctx->file_mode != new->ctx->file_mode || |
2943 | old->ctx->dir_mode != new->ctx->dir_mode) |
2944 | return 0; |
2945 | |
2946 | if (strcmp(old->local_nls->charset, new->local_nls->charset)) |
2947 | return 0; |
2948 | |
2949 | if (old->ctx->acregmax != new->ctx->acregmax) |
2950 | return 0; |
2951 | if (old->ctx->acdirmax != new->ctx->acdirmax) |
2952 | return 0; |
2953 | if (old->ctx->closetimeo != new->ctx->closetimeo) |
2954 | return 0; |
2955 | if (old->ctx->reparse_type != new->ctx->reparse_type) |
2956 | return 0; |
2957 | if (old->ctx->nonativesocket != new->ctx->nonativesocket) |
2958 | return 0; |
2959 | if (old->ctx->symlink_type != new->ctx->symlink_type) |
2960 | return 0; |
2961 | |
2962 | return 1; |
2963 | } |
2964 | |
2965 | static int match_prepath(struct super_block *sb, |
2966 | struct cifs_tcon *tcon, |
2967 | struct cifs_mnt_data *mnt_data) |
2968 | { |
2969 | struct smb3_fs_context *ctx = mnt_data->ctx; |
2970 | struct cifs_sb_info *old = CIFS_SB(sb); |
2971 | struct cifs_sb_info *new = mnt_data->cifs_sb; |
2972 | bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && |
2973 | old->prepath; |
2974 | bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && |
2975 | new->prepath; |
2976 | |
2977 | if (tcon->origin_fullpath && |
2978 | dfs_src_pathname_equal(s1: tcon->origin_fullpath, s2: ctx->source)) |
2979 | return 1; |
2980 | |
2981 | if (old_set && new_set && !strcmp(new->prepath, old->prepath)) |
2982 | return 1; |
2983 | else if (!old_set && !new_set) |
2984 | return 1; |
2985 | |
2986 | return 0; |
2987 | } |
2988 | |
2989 | int |
2990 | cifs_match_super(struct super_block *sb, void *data) |
2991 | { |
2992 | struct cifs_mnt_data *mnt_data = data; |
2993 | struct smb3_fs_context *ctx; |
2994 | struct cifs_sb_info *cifs_sb; |
2995 | struct TCP_Server_Info *tcp_srv; |
2996 | struct cifs_ses *ses; |
2997 | struct cifs_tcon *tcon; |
2998 | struct tcon_link *tlink; |
2999 | int rc = 0; |
3000 | |
3001 | spin_lock(lock: &cifs_tcp_ses_lock); |
3002 | cifs_sb = CIFS_SB(sb); |
3003 | |
3004 | /* We do not want to use a superblock that has been shutdown */ |
3005 | if (CIFS_MOUNT_SHUTDOWN & cifs_sb->mnt_cifs_flags) { |
3006 | spin_unlock(lock: &cifs_tcp_ses_lock); |
3007 | return 0; |
3008 | } |
3009 | |
3010 | tlink = cifs_get_tlink(tlink: cifs_sb_master_tlink(cifs_sb)); |
3011 | if (IS_ERR_OR_NULL(ptr: tlink)) { |
3012 | pr_warn_once("%s: skip super matching due to bad tlink(%p)\n" , |
3013 | __func__, tlink); |
3014 | spin_unlock(lock: &cifs_tcp_ses_lock); |
3015 | return 0; |
3016 | } |
3017 | tcon = tlink_tcon(tlink); |
3018 | ses = tcon->ses; |
3019 | tcp_srv = ses->server; |
3020 | |
3021 | ctx = mnt_data->ctx; |
3022 | |
3023 | spin_lock(lock: &tcp_srv->srv_lock); |
3024 | spin_lock(lock: &ses->ses_lock); |
3025 | spin_lock(lock: &ses->chan_lock); |
3026 | spin_lock(lock: &tcon->tc_lock); |
3027 | if (!match_server(server: tcp_srv, ctx, match_super: true) || |
3028 | !match_session(ses, ctx, match_super: true) || |
3029 | !match_tcon(tcon, ctx) || |
3030 | !match_prepath(sb, tcon, mnt_data)) { |
3031 | rc = 0; |
3032 | goto out; |
3033 | } |
3034 | |
3035 | rc = compare_mount_options(sb, mnt_data); |
3036 | out: |
3037 | spin_unlock(lock: &tcon->tc_lock); |
3038 | spin_unlock(lock: &ses->chan_lock); |
3039 | spin_unlock(lock: &ses->ses_lock); |
3040 | spin_unlock(lock: &tcp_srv->srv_lock); |
3041 | |
3042 | spin_unlock(lock: &cifs_tcp_ses_lock); |
3043 | cifs_put_tlink(tlink); |
3044 | return rc; |
3045 | } |
3046 | |
3047 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
3048 | static struct lock_class_key cifs_key[2]; |
3049 | static struct lock_class_key cifs_slock_key[2]; |
3050 | |
3051 | static inline void |
3052 | cifs_reclassify_socket4(struct socket *sock) |
3053 | { |
3054 | struct sock *sk = sock->sk; |
3055 | |
3056 | BUG_ON(!sock_allow_reclassification(sk)); |
3057 | sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS" , |
3058 | &cifs_slock_key[0], "sk_lock-AF_INET-CIFS" , &cifs_key[0]); |
3059 | } |
3060 | |
3061 | static inline void |
3062 | cifs_reclassify_socket6(struct socket *sock) |
3063 | { |
3064 | struct sock *sk = sock->sk; |
3065 | |
3066 | BUG_ON(!sock_allow_reclassification(sk)); |
3067 | sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS" , |
3068 | &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS" , &cifs_key[1]); |
3069 | } |
3070 | #else |
3071 | static inline void |
3072 | cifs_reclassify_socket4(struct socket *sock) |
3073 | { |
3074 | } |
3075 | |
3076 | static inline void |
3077 | cifs_reclassify_socket6(struct socket *sock) |
3078 | { |
3079 | } |
3080 | #endif |
3081 | |
3082 | /* See RFC1001 section 14 on representation of Netbios names */ |
3083 | static void rfc1002mangle(char *target, char *source, unsigned int length) |
3084 | { |
3085 | unsigned int i, j; |
3086 | |
3087 | for (i = 0, j = 0; i < (length); i++) { |
3088 | /* mask a nibble at a time and encode */ |
3089 | target[j] = 'A' + (0x0F & (source[i] >> 4)); |
3090 | target[j+1] = 'A' + (0x0F & source[i]); |
3091 | j += 2; |
3092 | } |
3093 | |
3094 | } |
3095 | |
3096 | static int |
3097 | bind_socket(struct TCP_Server_Info *server) |
3098 | { |
3099 | int rc = 0; |
3100 | |
3101 | if (server->srcaddr.ss_family != AF_UNSPEC) { |
3102 | /* Bind to the specified local IP address */ |
3103 | struct socket *socket = server->ssocket; |
3104 | |
3105 | rc = kernel_bind(sock: socket, |
3106 | addr: (struct sockaddr *) &server->srcaddr, |
3107 | addrlen: sizeof(server->srcaddr)); |
3108 | if (rc < 0) { |
3109 | struct sockaddr_in *saddr4; |
3110 | struct sockaddr_in6 *saddr6; |
3111 | |
3112 | saddr4 = (struct sockaddr_in *)&server->srcaddr; |
3113 | saddr6 = (struct sockaddr_in6 *)&server->srcaddr; |
3114 | if (saddr6->sin6_family == AF_INET6) |
3115 | cifs_server_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n" , |
3116 | &saddr6->sin6_addr, rc); |
3117 | else |
3118 | cifs_server_dbg(VFS, "Failed to bind to: %pI4, error: %d\n" , |
3119 | &saddr4->sin_addr.s_addr, rc); |
3120 | } |
3121 | } |
3122 | return rc; |
3123 | } |
3124 | |
3125 | static int |
3126 | smb_recv_kvec(struct TCP_Server_Info *server, struct msghdr *msg, size_t *recv) |
3127 | { |
3128 | int rc = 0; |
3129 | int retries = 0; |
3130 | int msg_flags = server->noblocksnd ? MSG_DONTWAIT : 0; |
3131 | |
3132 | *recv = 0; |
3133 | |
3134 | while (msg_data_left(msg)) { |
3135 | rc = sock_recvmsg(sock: server->ssocket, msg, flags: msg_flags); |
3136 | if (rc == -EAGAIN) { |
3137 | retries++; |
3138 | if (retries >= 14 || |
3139 | (!server->noblocksnd && (retries > 2))) { |
3140 | cifs_server_dbg(VFS, "sends on sock %p stuck for 15 seconds\n" , |
3141 | server->ssocket); |
3142 | return -EAGAIN; |
3143 | } |
3144 | msleep(msecs: 1 << retries); |
3145 | continue; |
3146 | } |
3147 | |
3148 | if (rc < 0) |
3149 | return rc; |
3150 | |
3151 | if (rc == 0) { |
3152 | cifs_dbg(FYI, "Received no data (TCP RST)\n" ); |
3153 | return -ECONNABORTED; |
3154 | } |
3155 | |
3156 | /* recv was at least partially successful */ |
3157 | *recv += rc; |
3158 | retries = 0; /* in case we get ENOSPC on the next send */ |
3159 | } |
3160 | return 0; |
3161 | } |
3162 | |
3163 | static int |
3164 | ip_rfc1001_connect(struct TCP_Server_Info *server) |
3165 | { |
3166 | int rc = 0; |
3167 | /* |
3168 | * some servers require RFC1001 sessinit before sending |
3169 | * negprot - BB check reconnection in case where second |
3170 | * sessinit is sent but no second negprot |
3171 | */ |
3172 | struct rfc1002_session_packet req = {}; |
3173 | struct rfc1002_session_packet resp = {}; |
3174 | struct msghdr msg = {}; |
3175 | struct kvec iov = {}; |
3176 | unsigned int len; |
3177 | size_t sent; |
3178 | size_t recv; |
3179 | |
3180 | req.trailer.session_req.called_len = sizeof(req.trailer.session_req.called_name); |
3181 | |
3182 | if (server->server_RFC1001_name[0] != 0) |
3183 | rfc1002mangle(target: req.trailer.session_req.called_name, |
3184 | source: server->server_RFC1001_name, |
3185 | RFC1001_NAME_LEN_WITH_NULL); |
3186 | else |
3187 | rfc1002mangle(target: req.trailer.session_req.called_name, |
3188 | DEFAULT_CIFS_CALLED_NAME, |
3189 | RFC1001_NAME_LEN_WITH_NULL); |
3190 | |
3191 | req.trailer.session_req.calling_len = sizeof(req.trailer.session_req.calling_name); |
3192 | |
3193 | /* calling name ends in null (byte 16) from old smb convention */ |
3194 | if (server->workstation_RFC1001_name[0] != 0) |
3195 | rfc1002mangle(target: req.trailer.session_req.calling_name, |
3196 | source: server->workstation_RFC1001_name, |
3197 | RFC1001_NAME_LEN_WITH_NULL); |
3198 | else |
3199 | rfc1002mangle(target: req.trailer.session_req.calling_name, |
3200 | source: "LINUX_CIFS_CLNT" , |
3201 | RFC1001_NAME_LEN_WITH_NULL); |
3202 | |
3203 | /* |
3204 | * As per rfc1002, @len must be the number of bytes that follows the |
3205 | * length field of a rfc1002 session request payload. |
3206 | */ |
3207 | len = sizeof(req.trailer.session_req); |
3208 | req.type = RFC1002_SESSION_REQUEST; |
3209 | req.flags = 0; |
3210 | req.length = cpu_to_be16(len); |
3211 | len += offsetof(typeof(req), trailer.session_req); |
3212 | iov.iov_base = &req; |
3213 | iov.iov_len = len; |
3214 | iov_iter_kvec(i: &msg.msg_iter, ITER_SOURCE, kvec: &iov, nr_segs: 1, count: len); |
3215 | rc = smb_send_kvec(server, msg: &msg, sent: &sent); |
3216 | if (rc < 0 || len != sent) |
3217 | return (rc == -EINTR || rc == -EAGAIN) ? rc : -ECONNABORTED; |
3218 | |
3219 | /* |
3220 | * RFC1001 layer in at least one server requires very short break before |
3221 | * negprot presumably because not expecting negprot to follow so fast. |
3222 | * For example DOS SMB servers cannot process negprot if it was received |
3223 | * before the server sent response for SESSION_REQUEST packet. So, wait |
3224 | * for the response, read it and parse it as it can contain useful error |
3225 | * information (e.g. specified server name was incorrect). For example |
3226 | * even the latest Windows Server 2022 SMB1 server over port 139 send |
3227 | * error if its server name was in SESSION_REQUEST packet incorrect. |
3228 | * Nowadays usage of port 139 is not common, so waiting for reply here |
3229 | * does not slowing down mounting of common case (over port 445). |
3230 | */ |
3231 | len = offsetof(typeof(resp), trailer); |
3232 | iov.iov_base = &resp; |
3233 | iov.iov_len = len; |
3234 | iov_iter_kvec(i: &msg.msg_iter, ITER_DEST, kvec: &iov, nr_segs: 1, count: len); |
3235 | rc = smb_recv_kvec(server, msg: &msg, recv: &recv); |
3236 | if (rc < 0 || recv != len) |
3237 | return (rc == -EINTR || rc == -EAGAIN) ? rc : -ECONNABORTED; |
3238 | |
3239 | switch (resp.type) { |
3240 | case RFC1002_POSITIVE_SESSION_RESPONSE: |
3241 | if (be16_to_cpu(resp.length) != 0) { |
3242 | cifs_dbg(VFS, "RFC 1002 positive session response but with invalid non-zero length %u\n" , |
3243 | be16_to_cpu(resp.length)); |
3244 | return -EIO; |
3245 | } |
3246 | cifs_dbg(FYI, "RFC 1002 positive session response" ); |
3247 | break; |
3248 | case RFC1002_NEGATIVE_SESSION_RESPONSE: |
3249 | /* Read RFC1002 response error code and convert it to errno in rc */ |
3250 | len = sizeof(resp.trailer.neg_ses_resp_error_code); |
3251 | iov.iov_base = &resp.trailer.neg_ses_resp_error_code; |
3252 | iov.iov_len = len; |
3253 | iov_iter_kvec(i: &msg.msg_iter, ITER_DEST, kvec: &iov, nr_segs: 1, count: len); |
3254 | if (be16_to_cpu(resp.length) == len && |
3255 | smb_recv_kvec(server, msg: &msg, recv: &recv) == 0 && |
3256 | recv == len) { |
3257 | cifs_dbg(VFS, "RFC 1002 negative session response with error 0x%x\n" , |
3258 | resp.trailer.neg_ses_resp_error_code); |
3259 | switch (resp.trailer.neg_ses_resp_error_code) { |
3260 | case RFC1002_NOT_LISTENING_CALLED: |
3261 | /* server does not listen for specified server name */ |
3262 | fallthrough; |
3263 | case RFC1002_NOT_PRESENT: |
3264 | /* server name is incorrect */ |
3265 | rc = -ENOENT; |
3266 | cifs_dbg(VFS, "Server rejected NetBIOS servername %.15s\n" , |
3267 | server->server_RFC1001_name[0] ? |
3268 | server->server_RFC1001_name : |
3269 | DEFAULT_CIFS_CALLED_NAME); |
3270 | cifs_dbg(VFS, "Specify correct NetBIOS servername in source path or with -o servern= option\n" ); |
3271 | break; |
3272 | case RFC1002_NOT_LISTENING_CALLING: |
3273 | /* client name was not accepted by server */ |
3274 | rc = -EACCES; |
3275 | cifs_dbg(VFS, "Server rejected NetBIOS clientname %.15s\n" , |
3276 | server->workstation_RFC1001_name[0] ? |
3277 | server->workstation_RFC1001_name : |
3278 | "LINUX_CIFS_CLNT" ); |
3279 | cifs_dbg(VFS, "Specify correct NetBIOS clientname with -o netbiosname= option\n" ); |
3280 | break; |
3281 | case RFC1002_INSUFFICIENT_RESOURCE: |
3282 | /* remote server resource error */ |
3283 | rc = -EREMOTEIO; |
3284 | break; |
3285 | case RFC1002_UNSPECIFIED_ERROR: |
3286 | default: |
3287 | /* other/unknown error */ |
3288 | rc = -EIO; |
3289 | break; |
3290 | } |
3291 | } else { |
3292 | cifs_dbg(VFS, "RFC 1002 negative session response\n" ); |
3293 | rc = -EIO; |
3294 | } |
3295 | return rc; |
3296 | case RFC1002_RETARGET_SESSION_RESPONSE: |
3297 | cifs_dbg(VFS, "RFC 1002 retarget session response\n" ); |
3298 | if (be16_to_cpu(resp.length) == sizeof(resp.trailer.retarget_resp)) { |
3299 | len = sizeof(resp.trailer.retarget_resp); |
3300 | iov.iov_base = &resp.trailer.retarget_resp; |
3301 | iov.iov_len = len; |
3302 | iov_iter_kvec(i: &msg.msg_iter, ITER_DEST, kvec: &iov, nr_segs: 1, count: len); |
3303 | if (smb_recv_kvec(server, msg: &msg, recv: &recv) == 0 && recv == len) { |
3304 | cifs_dbg(VFS, "Server wants to redirect connection\n" ); |
3305 | cifs_dbg(VFS, "Remount with options -o ip=%pI4,port=%u\n" , |
3306 | &resp.trailer.retarget_resp.retarget_ip_addr, |
3307 | be16_to_cpu(resp.trailer.retarget_resp.port)); |
3308 | } |
3309 | } |
3310 | cifs_dbg(VFS, "Closing connection\n" ); |
3311 | /* FIXME: Should we automatically redirect to new retarget_resp server? */ |
3312 | return -EMULTIHOP; |
3313 | default: |
3314 | cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n" , resp.type); |
3315 | return -EIO; |
3316 | } |
3317 | |
3318 | server->with_rfc1001 = true; |
3319 | return 0; |
3320 | } |
3321 | |
3322 | static int |
3323 | generic_ip_connect(struct TCP_Server_Info *server) |
3324 | { |
3325 | struct sockaddr *saddr; |
3326 | struct socket *socket; |
3327 | int slen, sfamily; |
3328 | __be16 sport; |
3329 | int rc = 0; |
3330 | |
3331 | saddr = (struct sockaddr *) &server->dstaddr; |
3332 | |
3333 | if (server->dstaddr.ss_family == AF_INET6) { |
3334 | struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr; |
3335 | |
3336 | sport = ipv6->sin6_port; |
3337 | slen = sizeof(struct sockaddr_in6); |
3338 | sfamily = AF_INET6; |
3339 | cifs_dbg(FYI, "%s: connecting to [%pI6]:%d\n" , __func__, &ipv6->sin6_addr, |
3340 | ntohs(sport)); |
3341 | } else { |
3342 | struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr; |
3343 | |
3344 | sport = ipv4->sin_port; |
3345 | slen = sizeof(struct sockaddr_in); |
3346 | sfamily = AF_INET; |
3347 | cifs_dbg(FYI, "%s: connecting to %pI4:%d\n" , __func__, &ipv4->sin_addr, |
3348 | ntohs(sport)); |
3349 | } |
3350 | |
3351 | if (server->ssocket) { |
3352 | socket = server->ssocket; |
3353 | } else { |
3354 | struct net *net = cifs_net_ns(srv: server); |
3355 | struct sock *sk; |
3356 | |
3357 | rc = __sock_create(net, family: sfamily, type: SOCK_STREAM, |
3358 | IPPROTO_TCP, res: &server->ssocket, kern: 1); |
3359 | if (rc < 0) { |
3360 | cifs_server_dbg(VFS, "Error %d creating socket\n" , rc); |
3361 | return rc; |
3362 | } |
3363 | |
3364 | sk = server->ssocket->sk; |
3365 | __netns_tracker_free(net, tracker: &sk->ns_tracker, refcounted: false); |
3366 | sk->sk_net_refcnt = 1; |
3367 | get_net_track(net, tracker: &sk->ns_tracker, GFP_KERNEL); |
3368 | sock_inuse_add(net, val: 1); |
3369 | |
3370 | /* BB other socket options to set KEEPALIVE, NODELAY? */ |
3371 | cifs_dbg(FYI, "Socket created\n" ); |
3372 | socket = server->ssocket; |
3373 | socket->sk->sk_allocation = GFP_NOFS; |
3374 | socket->sk->sk_use_task_frag = false; |
3375 | if (sfamily == AF_INET6) |
3376 | cifs_reclassify_socket6(sock: socket); |
3377 | else |
3378 | cifs_reclassify_socket4(sock: socket); |
3379 | } |
3380 | |
3381 | rc = bind_socket(server); |
3382 | if (rc < 0) |
3383 | return rc; |
3384 | |
3385 | /* |
3386 | * Eventually check for other socket options to change from |
3387 | * the default. sock_setsockopt not used because it expects |
3388 | * user space buffer |
3389 | */ |
3390 | socket->sk->sk_rcvtimeo = 7 * HZ; |
3391 | socket->sk->sk_sndtimeo = 5 * HZ; |
3392 | |
3393 | /* make the bufsizes depend on wsize/rsize and max requests */ |
3394 | if (server->noautotune) { |
3395 | if (socket->sk->sk_sndbuf < (200 * 1024)) |
3396 | socket->sk->sk_sndbuf = 200 * 1024; |
3397 | if (socket->sk->sk_rcvbuf < (140 * 1024)) |
3398 | socket->sk->sk_rcvbuf = 140 * 1024; |
3399 | } |
3400 | |
3401 | if (server->tcp_nodelay) |
3402 | tcp_sock_set_nodelay(sk: socket->sk); |
3403 | |
3404 | cifs_dbg(FYI, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx\n" , |
3405 | socket->sk->sk_sndbuf, |
3406 | socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); |
3407 | |
3408 | rc = kernel_connect(sock: socket, addr: saddr, addrlen: slen, |
3409 | flags: server->noblockcnt ? O_NONBLOCK : 0); |
3410 | /* |
3411 | * When mounting SMB root file systems, we do not want to block in |
3412 | * connect. Otherwise bail out and then let cifs_reconnect() perform |
3413 | * reconnect failover - if possible. |
3414 | */ |
3415 | if (server->noblockcnt && rc == -EINPROGRESS) |
3416 | rc = 0; |
3417 | if (rc < 0) { |
3418 | cifs_dbg(FYI, "Error %d connecting to server\n" , rc); |
3419 | trace_smb3_connect_err(hostname: server->hostname, conn_id: server->conn_id, addr: &server->dstaddr, rc); |
3420 | sock_release(sock: socket); |
3421 | server->ssocket = NULL; |
3422 | return rc; |
3423 | } |
3424 | trace_smb3_connect_done(hostname: server->hostname, conn_id: server->conn_id, addr: &server->dstaddr); |
3425 | |
3426 | /* |
3427 | * Establish RFC1001 NetBIOS session when it was explicitly requested |
3428 | * by mount option -o nbsessinit, or when connecting to default RFC1001 |
3429 | * server port (139) and it was not explicitly disabled by mount option |
3430 | * -o nonbsessinit. |
3431 | */ |
3432 | if (server->with_rfc1001 || |
3433 | server->rfc1001_sessinit == 1 || |
3434 | (server->rfc1001_sessinit == -1 && sport == htons(RFC1001_PORT))) |
3435 | rc = ip_rfc1001_connect(server); |
3436 | |
3437 | return rc; |
3438 | } |
3439 | |
3440 | static int |
3441 | ip_connect(struct TCP_Server_Info *server) |
3442 | { |
3443 | __be16 *sport; |
3444 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; |
3445 | struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; |
3446 | |
3447 | if (server->dstaddr.ss_family == AF_INET6) |
3448 | sport = &addr6->sin6_port; |
3449 | else |
3450 | sport = &addr->sin_port; |
3451 | |
3452 | if (*sport == 0) { |
3453 | int rc; |
3454 | |
3455 | /* try with 445 port at first */ |
3456 | *sport = htons(CIFS_PORT); |
3457 | |
3458 | rc = generic_ip_connect(server); |
3459 | if (rc >= 0) |
3460 | return rc; |
3461 | |
3462 | /* if it failed, try with 139 port */ |
3463 | *sport = htons(RFC1001_PORT); |
3464 | } |
3465 | |
3466 | return generic_ip_connect(server); |
3467 | } |
3468 | |
3469 | #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY |
3470 | void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, |
3471 | struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) |
3472 | { |
3473 | /* |
3474 | * If we are reconnecting then should we check to see if |
3475 | * any requested capabilities changed locally e.g. via |
3476 | * remount but we can not do much about it here |
3477 | * if they have (even if we could detect it by the following) |
3478 | * Perhaps we could add a backpointer to array of sb from tcon |
3479 | * or if we change to make all sb to same share the same |
3480 | * sb as NFS - then we only have one backpointer to sb. |
3481 | * What if we wanted to mount the server share twice once with |
3482 | * and once without posixacls or posix paths? |
3483 | */ |
3484 | __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); |
3485 | |
3486 | if (ctx && ctx->no_linux_ext) { |
3487 | tcon->fsUnixInfo.Capability = 0; |
3488 | tcon->unix_ext = 0; /* Unix Extensions disabled */ |
3489 | cifs_dbg(FYI, "Linux protocol extensions disabled\n" ); |
3490 | return; |
3491 | } else if (ctx) |
3492 | tcon->unix_ext = 1; /* Unix Extensions supported */ |
3493 | |
3494 | if (!tcon->unix_ext) { |
3495 | cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n" ); |
3496 | return; |
3497 | } |
3498 | |
3499 | if (!CIFSSMBQFSUnixInfo(xid, tcon)) { |
3500 | __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); |
3501 | |
3502 | cifs_dbg(FYI, "unix caps which server supports %lld\n" , cap); |
3503 | /* |
3504 | * check for reconnect case in which we do not |
3505 | * want to change the mount behavior if we can avoid it |
3506 | */ |
3507 | if (ctx == NULL) { |
3508 | /* |
3509 | * turn off POSIX ACL and PATHNAMES if not set |
3510 | * originally at mount time |
3511 | */ |
3512 | if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) |
3513 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
3514 | if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { |
3515 | if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) |
3516 | cifs_dbg(VFS, "POSIXPATH support change\n" ); |
3517 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; |
3518 | } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { |
3519 | cifs_dbg(VFS, "possible reconnect error\n" ); |
3520 | cifs_dbg(VFS, "server disabled POSIX path support\n" ); |
3521 | } |
3522 | } |
3523 | |
3524 | if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) |
3525 | cifs_dbg(VFS, "per-share encryption not supported yet\n" ); |
3526 | |
3527 | cap &= CIFS_UNIX_CAP_MASK; |
3528 | if (ctx && ctx->no_psx_acl) |
3529 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
3530 | else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { |
3531 | cifs_dbg(FYI, "negotiated posix acl support\n" ); |
3532 | if (cifs_sb) |
3533 | cifs_sb->mnt_cifs_flags |= |
3534 | CIFS_MOUNT_POSIXACL; |
3535 | } |
3536 | |
3537 | if (ctx && ctx->posix_paths == 0) |
3538 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; |
3539 | else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { |
3540 | cifs_dbg(FYI, "negotiate posix pathnames\n" ); |
3541 | if (cifs_sb) |
3542 | cifs_sb->mnt_cifs_flags |= |
3543 | CIFS_MOUNT_POSIX_PATHS; |
3544 | } |
3545 | |
3546 | cifs_dbg(FYI, "Negotiate caps 0x%x\n" , (int)cap); |
3547 | #ifdef CONFIG_CIFS_DEBUG2 |
3548 | if (cap & CIFS_UNIX_FCNTL_CAP) |
3549 | cifs_dbg(FYI, "FCNTL cap\n" ); |
3550 | if (cap & CIFS_UNIX_EXTATTR_CAP) |
3551 | cifs_dbg(FYI, "EXTATTR cap\n" ); |
3552 | if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) |
3553 | cifs_dbg(FYI, "POSIX path cap\n" ); |
3554 | if (cap & CIFS_UNIX_XATTR_CAP) |
3555 | cifs_dbg(FYI, "XATTR cap\n" ); |
3556 | if (cap & CIFS_UNIX_POSIX_ACL_CAP) |
3557 | cifs_dbg(FYI, "POSIX ACL cap\n" ); |
3558 | if (cap & CIFS_UNIX_LARGE_READ_CAP) |
3559 | cifs_dbg(FYI, "very large read cap\n" ); |
3560 | if (cap & CIFS_UNIX_LARGE_WRITE_CAP) |
3561 | cifs_dbg(FYI, "very large write cap\n" ); |
3562 | if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP) |
3563 | cifs_dbg(FYI, "transport encryption cap\n" ); |
3564 | if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) |
3565 | cifs_dbg(FYI, "mandatory transport encryption cap\n" ); |
3566 | #endif /* CIFS_DEBUG2 */ |
3567 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { |
3568 | if (ctx == NULL) |
3569 | cifs_dbg(FYI, "resetting capabilities failed\n" ); |
3570 | else |
3571 | cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n" ); |
3572 | |
3573 | } |
3574 | } |
3575 | } |
3576 | #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ |
3577 | |
3578 | int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb) |
3579 | { |
3580 | struct smb3_fs_context *ctx = cifs_sb->ctx; |
3581 | |
3582 | INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); |
3583 | INIT_LIST_HEAD(list: &cifs_sb->tcon_sb_link); |
3584 | |
3585 | spin_lock_init(&cifs_sb->tlink_tree_lock); |
3586 | cifs_sb->tlink_tree = RB_ROOT; |
3587 | |
3588 | cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n" , |
3589 | ctx->file_mode, ctx->dir_mode); |
3590 | |
3591 | /* this is needed for ASCII cp to Unicode converts */ |
3592 | if (ctx->iocharset == NULL) { |
3593 | /* load_nls_default cannot return null */ |
3594 | cifs_sb->local_nls = load_nls_default(); |
3595 | } else { |
3596 | cifs_sb->local_nls = load_nls(charset: ctx->iocharset); |
3597 | if (cifs_sb->local_nls == NULL) { |
3598 | cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n" , |
3599 | ctx->iocharset); |
3600 | return -ELIBACC; |
3601 | } |
3602 | } |
3603 | ctx->local_nls = cifs_sb->local_nls; |
3604 | |
3605 | smb3_update_mnt_flags(cifs_sb); |
3606 | |
3607 | if (ctx->direct_io) |
3608 | cifs_dbg(FYI, "mounting share using direct i/o\n" ); |
3609 | if (ctx->cache_ro) { |
3610 | cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n" ); |
3611 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; |
3612 | } else if (ctx->cache_rw) { |
3613 | cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n" ); |
3614 | cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | |
3615 | CIFS_MOUNT_RW_CACHE); |
3616 | } |
3617 | |
3618 | if ((ctx->cifs_acl) && (ctx->dynperm)) |
3619 | cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n" ); |
3620 | |
3621 | if (ctx->prepath) { |
3622 | cifs_sb->prepath = kstrdup(s: ctx->prepath, GFP_KERNEL); |
3623 | if (cifs_sb->prepath == NULL) |
3624 | return -ENOMEM; |
3625 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; |
3626 | } |
3627 | |
3628 | return 0; |
3629 | } |
3630 | |
3631 | /* Release all succeed connections */ |
3632 | void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx) |
3633 | { |
3634 | int rc = 0; |
3635 | |
3636 | if (mnt_ctx->tcon) |
3637 | cifs_put_tcon(tcon: mnt_ctx->tcon, trace: netfs_trace_tcon_ref_put_mnt_ctx); |
3638 | else if (mnt_ctx->ses) |
3639 | cifs_put_smb_ses(ses: mnt_ctx->ses); |
3640 | else if (mnt_ctx->server) |
3641 | cifs_put_tcp_session(server: mnt_ctx->server, from_reconnect: 0); |
3642 | mnt_ctx->ses = NULL; |
3643 | mnt_ctx->tcon = NULL; |
3644 | mnt_ctx->server = NULL; |
3645 | mnt_ctx->cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS; |
3646 | free_xid(mnt_ctx->xid); |
3647 | } |
3648 | |
3649 | int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx) |
3650 | { |
3651 | struct TCP_Server_Info *server = NULL; |
3652 | struct smb3_fs_context *ctx; |
3653 | struct cifs_ses *ses = NULL; |
3654 | unsigned int xid; |
3655 | int rc = 0; |
3656 | |
3657 | xid = get_xid(); |
3658 | |
3659 | if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->fs_ctx)) { |
3660 | rc = -EINVAL; |
3661 | goto out; |
3662 | } |
3663 | ctx = mnt_ctx->fs_ctx; |
3664 | |
3665 | /* get a reference to a tcp session */ |
3666 | server = cifs_get_tcp_session(ctx, NULL); |
3667 | if (IS_ERR(ptr: server)) { |
3668 | rc = PTR_ERR(ptr: server); |
3669 | server = NULL; |
3670 | goto out; |
3671 | } |
3672 | |
3673 | /* get a reference to a SMB session */ |
3674 | ses = cifs_get_smb_ses(server, ctx); |
3675 | if (IS_ERR(ptr: ses)) { |
3676 | rc = PTR_ERR(ptr: ses); |
3677 | ses = NULL; |
3678 | goto out; |
3679 | } |
3680 | |
3681 | if ((ctx->persistent == true) && (!(ses->server->capabilities & |
3682 | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) { |
3683 | cifs_server_dbg(VFS, "persistent handles not supported by server\n" ); |
3684 | rc = -EOPNOTSUPP; |
3685 | } |
3686 | |
3687 | out: |
3688 | mnt_ctx->xid = xid; |
3689 | mnt_ctx->server = server; |
3690 | mnt_ctx->ses = ses; |
3691 | mnt_ctx->tcon = NULL; |
3692 | |
3693 | return rc; |
3694 | } |
3695 | |
3696 | int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx) |
3697 | { |
3698 | struct TCP_Server_Info *server; |
3699 | struct cifs_sb_info *cifs_sb; |
3700 | struct smb3_fs_context *ctx; |
3701 | struct cifs_tcon *tcon = NULL; |
3702 | int rc = 0; |
3703 | |
3704 | if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->server || !mnt_ctx->ses || !mnt_ctx->fs_ctx || |
3705 | !mnt_ctx->cifs_sb)) { |
3706 | rc = -EINVAL; |
3707 | goto out; |
3708 | } |
3709 | server = mnt_ctx->server; |
3710 | ctx = mnt_ctx->fs_ctx; |
3711 | cifs_sb = mnt_ctx->cifs_sb; |
3712 | |
3713 | /* search for existing tcon to this server share */ |
3714 | tcon = cifs_get_tcon(ses: mnt_ctx->ses, ctx); |
3715 | if (IS_ERR(ptr: tcon)) { |
3716 | rc = PTR_ERR(ptr: tcon); |
3717 | tcon = NULL; |
3718 | goto out; |
3719 | } |
3720 | |
3721 | /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ |
3722 | if (tcon->posix_extensions) |
3723 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; |
3724 | |
3725 | #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY |
3726 | /* tell server which Unix caps we support */ |
3727 | if (cap_unix(ses: tcon->ses)) { |
3728 | /* |
3729 | * reset of caps checks mount to see if unix extensions disabled |
3730 | * for just this mount. |
3731 | */ |
3732 | reset_cifs_unix_caps(xid: mnt_ctx->xid, tcon, cifs_sb, ctx); |
3733 | spin_lock(lock: &tcon->ses->server->srv_lock); |
3734 | if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && |
3735 | (le64_to_cpu(tcon->fsUnixInfo.Capability) & |
3736 | CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { |
3737 | spin_unlock(lock: &tcon->ses->server->srv_lock); |
3738 | rc = -EACCES; |
3739 | goto out; |
3740 | } |
3741 | spin_unlock(lock: &tcon->ses->server->srv_lock); |
3742 | } else |
3743 | #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ |
3744 | tcon->unix_ext = 0; /* server does not support them */ |
3745 | |
3746 | /* do not care if a following call succeed - informational */ |
3747 | if (!tcon->pipe && server->ops->qfs_tcon) { |
3748 | server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb); |
3749 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { |
3750 | if (tcon->fsDevInfo.DeviceCharacteristics & |
3751 | cpu_to_le32(FILE_READ_ONLY_DEVICE)) |
3752 | cifs_dbg(VFS, "mounted to read only share\n" ); |
3753 | else if ((cifs_sb->mnt_cifs_flags & |
3754 | CIFS_MOUNT_RW_CACHE) == 0) |
3755 | cifs_dbg(VFS, "read only mount of RW share\n" ); |
3756 | /* no need to log a RW mount of a typical RW share */ |
3757 | } |
3758 | } |
3759 | |
3760 | cifs_negotiate_iosize(server, ctx: cifs_sb->ctx, tcon); |
3761 | /* |
3762 | * The cookie is initialized from volume info returned above. |
3763 | * Inside cifs_fscache_get_super_cookie it checks |
3764 | * that we do not get super cookie twice. |
3765 | */ |
3766 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) |
3767 | cifs_fscache_get_super_cookie(tcon); |
3768 | |
3769 | out: |
3770 | mnt_ctx->tcon = tcon; |
3771 | return rc; |
3772 | } |
3773 | |
3774 | static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, |
3775 | struct cifs_tcon *tcon) |
3776 | { |
3777 | struct tcon_link *tlink; |
3778 | |
3779 | /* hang the tcon off of the superblock */ |
3780 | tlink = kzalloc(sizeof(*tlink), GFP_KERNEL); |
3781 | if (tlink == NULL) |
3782 | return -ENOMEM; |
3783 | |
3784 | tlink->tl_uid = ses->linux_uid; |
3785 | tlink->tl_tcon = tcon; |
3786 | tlink->tl_time = jiffies; |
3787 | set_bit(TCON_LINK_MASTER, addr: &tlink->tl_flags); |
3788 | set_bit(TCON_LINK_IN_TREE, addr: &tlink->tl_flags); |
3789 | |
3790 | cifs_sb->master_tlink = tlink; |
3791 | spin_lock(lock: &cifs_sb->tlink_tree_lock); |
3792 | tlink_rb_insert(root: &cifs_sb->tlink_tree, new_tlink: tlink); |
3793 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
3794 | |
3795 | spin_lock(lock: &tcon->sb_list_lock); |
3796 | list_add(new: &cifs_sb->tcon_sb_link, head: &tcon->cifs_sb_list); |
3797 | spin_unlock(lock: &tcon->sb_list_lock); |
3798 | |
3799 | queue_delayed_work(wq: cifsiod_wq, dwork: &cifs_sb->prune_tlinks, |
3800 | TLINK_IDLE_EXPIRE); |
3801 | return 0; |
3802 | } |
3803 | |
3804 | static int |
3805 | cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, |
3806 | unsigned int xid, |
3807 | struct cifs_tcon *tcon, |
3808 | struct cifs_sb_info *cifs_sb, |
3809 | char *full_path, |
3810 | int added_treename) |
3811 | { |
3812 | int rc; |
3813 | char *s; |
3814 | char sep, tmp; |
3815 | int skip = added_treename ? 1 : 0; |
3816 | |
3817 | sep = CIFS_DIR_SEP(cifs_sb); |
3818 | s = full_path; |
3819 | |
3820 | rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, "" ); |
3821 | while (rc == 0) { |
3822 | /* skip separators */ |
3823 | while (*s == sep) |
3824 | s++; |
3825 | if (!*s) |
3826 | break; |
3827 | /* next separator */ |
3828 | while (*s && *s != sep) |
3829 | s++; |
3830 | /* |
3831 | * if the treename is added, we then have to skip the first |
3832 | * part within the separators |
3833 | */ |
3834 | if (skip) { |
3835 | skip = 0; |
3836 | continue; |
3837 | } |
3838 | /* |
3839 | * temporarily null-terminate the path at the end of |
3840 | * the current component |
3841 | */ |
3842 | tmp = *s; |
3843 | *s = 0; |
3844 | rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, |
3845 | full_path); |
3846 | *s = tmp; |
3847 | } |
3848 | return rc; |
3849 | } |
3850 | |
3851 | /* |
3852 | * Check if path is remote (i.e. a DFS share). |
3853 | * |
3854 | * Return -EREMOTE if it is, otherwise 0 or -errno. |
3855 | */ |
3856 | int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx) |
3857 | { |
3858 | int rc; |
3859 | struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; |
3860 | struct TCP_Server_Info *server = mnt_ctx->server; |
3861 | unsigned int xid = mnt_ctx->xid; |
3862 | struct cifs_tcon *tcon = mnt_ctx->tcon; |
3863 | struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; |
3864 | char *full_path; |
3865 | |
3866 | if (!server->ops->is_path_accessible) |
3867 | return -EOPNOTSUPP; |
3868 | |
3869 | /* |
3870 | * cifs_build_path_to_root works only when we have a valid tcon |
3871 | */ |
3872 | full_path = cifs_build_path_to_root(ctx, cifs_sb, tcon, |
3873 | add_treename: tcon->Flags & SMB_SHARE_IS_IN_DFS); |
3874 | if (full_path == NULL) |
3875 | return -ENOMEM; |
3876 | |
3877 | cifs_dbg(FYI, "%s: full_path: %s\n" , __func__, full_path); |
3878 | |
3879 | rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, |
3880 | full_path); |
3881 | if (rc != 0 && rc != -EREMOTE) |
3882 | goto out; |
3883 | |
3884 | if (rc != -EREMOTE) { |
3885 | rc = cifs_are_all_path_components_accessible(server, xid, tcon, |
3886 | cifs_sb, full_path, added_treename: tcon->Flags & SMB_SHARE_IS_IN_DFS); |
3887 | if (rc != 0) { |
3888 | cifs_server_dbg(VFS, "cannot query dirs between root and final path, enabling CIFS_MOUNT_USE_PREFIX_PATH\n" ); |
3889 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; |
3890 | rc = 0; |
3891 | } |
3892 | } |
3893 | |
3894 | out: |
3895 | kfree(objp: full_path); |
3896 | return rc; |
3897 | } |
3898 | |
3899 | #ifdef CONFIG_CIFS_DFS_UPCALL |
3900 | int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) |
3901 | { |
3902 | struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, }; |
3903 | int rc; |
3904 | |
3905 | rc = dfs_mount_share(mnt_ctx: &mnt_ctx); |
3906 | if (rc) |
3907 | goto error; |
3908 | if (!ctx->dfs_conn) |
3909 | goto out; |
3910 | |
3911 | /* |
3912 | * After reconnecting to a different server, unique ids won't match anymore, so we disable |
3913 | * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE). |
3914 | */ |
3915 | cifs_autodisable_serverino(cifs_sb); |
3916 | /* |
3917 | * Force the use of prefix path to support failover on DFS paths that resolve to targets |
3918 | * that have different prefix paths. |
3919 | */ |
3920 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; |
3921 | kfree(objp: cifs_sb->prepath); |
3922 | cifs_sb->prepath = ctx->prepath; |
3923 | ctx->prepath = NULL; |
3924 | |
3925 | out: |
3926 | cifs_try_adding_channels(ses: mnt_ctx.ses); |
3927 | rc = mount_setup_tlink(cifs_sb, ses: mnt_ctx.ses, tcon: mnt_ctx.tcon); |
3928 | if (rc) |
3929 | goto error; |
3930 | |
3931 | free_xid(mnt_ctx.xid); |
3932 | return rc; |
3933 | |
3934 | error: |
3935 | cifs_mount_put_conns(mnt_ctx: &mnt_ctx); |
3936 | return rc; |
3937 | } |
3938 | #else |
3939 | int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) |
3940 | { |
3941 | int rc = 0; |
3942 | struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, }; |
3943 | |
3944 | rc = cifs_mount_get_session(&mnt_ctx); |
3945 | if (rc) |
3946 | goto error; |
3947 | |
3948 | rc = cifs_mount_get_tcon(&mnt_ctx); |
3949 | if (!rc) { |
3950 | /* |
3951 | * Prevent superblock from being created with any missing |
3952 | * connections. |
3953 | */ |
3954 | if (WARN_ON(!mnt_ctx.server)) |
3955 | rc = -EHOSTDOWN; |
3956 | else if (WARN_ON(!mnt_ctx.ses)) |
3957 | rc = -EACCES; |
3958 | else if (WARN_ON(!mnt_ctx.tcon)) |
3959 | rc = -ENOENT; |
3960 | } |
3961 | if (rc) |
3962 | goto error; |
3963 | |
3964 | rc = cifs_is_path_remote(&mnt_ctx); |
3965 | if (rc == -EREMOTE) |
3966 | rc = -EOPNOTSUPP; |
3967 | if (rc) |
3968 | goto error; |
3969 | |
3970 | rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon); |
3971 | if (rc) |
3972 | goto error; |
3973 | |
3974 | free_xid(mnt_ctx.xid); |
3975 | return rc; |
3976 | |
3977 | error: |
3978 | cifs_mount_put_conns(&mnt_ctx); |
3979 | return rc; |
3980 | } |
3981 | #endif |
3982 | |
3983 | #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY |
3984 | /* |
3985 | * Issue a TREE_CONNECT request. |
3986 | */ |
3987 | int |
3988 | CIFSTCon(const unsigned int xid, struct cifs_ses *ses, |
3989 | const char *tree, struct cifs_tcon *tcon, |
3990 | const struct nls_table *nls_codepage) |
3991 | { |
3992 | struct smb_hdr *smb_buffer; |
3993 | struct smb_hdr *smb_buffer_response; |
3994 | TCONX_REQ *pSMB; |
3995 | TCONX_RSP *pSMBr; |
3996 | unsigned char *bcc_ptr; |
3997 | int rc = 0; |
3998 | int length; |
3999 | __u16 bytes_left, count; |
4000 | |
4001 | if (ses == NULL) |
4002 | return -EIO; |
4003 | |
4004 | smb_buffer = cifs_buf_get(); |
4005 | if (smb_buffer == NULL) |
4006 | return -ENOMEM; |
4007 | |
4008 | smb_buffer_response = smb_buffer; |
4009 | |
4010 | header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, |
4011 | NULL /*no tid */, 4 /*wct */); |
4012 | |
4013 | smb_buffer->Mid = get_next_mid(server: ses->server); |
4014 | smb_buffer->Uid = ses->Suid; |
4015 | pSMB = (TCONX_REQ *) smb_buffer; |
4016 | pSMBr = (TCONX_RSP *) smb_buffer_response; |
4017 | |
4018 | pSMB->AndXCommand = 0xFF; |
4019 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); |
4020 | bcc_ptr = &pSMB->Password[0]; |
4021 | |
4022 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ |
4023 | *bcc_ptr = 0; /* password is null byte */ |
4024 | bcc_ptr++; /* skip password */ |
4025 | /* already aligned so no need to do it below */ |
4026 | |
4027 | if (ses->server->sign) |
4028 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; |
4029 | |
4030 | if (ses->capabilities & CAP_STATUS32) |
4031 | smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS; |
4032 | |
4033 | if (ses->capabilities & CAP_DFS) |
4034 | smb_buffer->Flags2 |= SMBFLG2_DFS; |
4035 | |
4036 | if (ses->capabilities & CAP_UNICODE) { |
4037 | smb_buffer->Flags2 |= SMBFLG2_UNICODE; |
4038 | length = |
4039 | cifs_strtoUTF16((__le16 *) bcc_ptr, tree, |
4040 | 6 /* max utf8 char length in bytes */ * |
4041 | (/* server len*/ + 256 /* share len */), nls_codepage); |
4042 | bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */ |
4043 | bcc_ptr += 2; /* skip trailing null */ |
4044 | } else { /* ASCII */ |
4045 | strcpy(p: bcc_ptr, q: tree); |
4046 | bcc_ptr += strlen(tree) + 1; |
4047 | } |
4048 | strcpy(p: bcc_ptr, q: "?????" ); |
4049 | bcc_ptr += strlen("?????" ); |
4050 | bcc_ptr += 1; |
4051 | count = bcc_ptr - &pSMB->Password[0]; |
4052 | be32_add_cpu(var: &pSMB->hdr.smb_buf_length, val: count); |
4053 | pSMB->ByteCount = cpu_to_le16(count); |
4054 | |
4055 | rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, |
4056 | 0); |
4057 | |
4058 | /* above now done in SendReceive */ |
4059 | if (rc == 0) { |
4060 | bool is_unicode; |
4061 | |
4062 | tcon->tid = smb_buffer_response->Tid; |
4063 | bcc_ptr = pByteArea(smb_buffer_response); |
4064 | bytes_left = get_bcc(hdr: smb_buffer_response); |
4065 | length = strnlen(p: bcc_ptr, maxlen: bytes_left - 2); |
4066 | if (smb_buffer->Flags2 & SMBFLG2_UNICODE) |
4067 | is_unicode = true; |
4068 | else |
4069 | is_unicode = false; |
4070 | |
4071 | |
4072 | /* skip service field (NB: this field is always ASCII) */ |
4073 | if (length == 3) { |
4074 | if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') && |
4075 | (bcc_ptr[2] == 'C')) { |
4076 | cifs_dbg(FYI, "IPC connection\n" ); |
4077 | tcon->ipc = true; |
4078 | tcon->pipe = true; |
4079 | } |
4080 | } else if (length == 2) { |
4081 | if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) { |
4082 | /* the most common case */ |
4083 | cifs_dbg(FYI, "disk share connection\n" ); |
4084 | } |
4085 | } |
4086 | bcc_ptr += length + 1; |
4087 | bytes_left -= (length + 1); |
4088 | strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name)); |
4089 | |
4090 | /* mostly informational -- no need to fail on error here */ |
4091 | kfree(objp: tcon->nativeFileSystem); |
4092 | tcon->nativeFileSystem = cifs_strndup_from_utf16(src: bcc_ptr, |
4093 | maxlen: bytes_left, is_unicode, |
4094 | codepage: nls_codepage); |
4095 | |
4096 | cifs_dbg(FYI, "nativeFileSystem=%s\n" , tcon->nativeFileSystem); |
4097 | |
4098 | if ((smb_buffer_response->WordCount == 3) || |
4099 | (smb_buffer_response->WordCount == 7)) |
4100 | /* field is in same location */ |
4101 | tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); |
4102 | else |
4103 | tcon->Flags = 0; |
4104 | cifs_dbg(FYI, "Tcon flags: 0x%x\n" , tcon->Flags); |
4105 | |
4106 | /* |
4107 | * reset_cifs_unix_caps calls QFSInfo which requires |
4108 | * need_reconnect to be false, but we would not need to call |
4109 | * reset_caps if this were not a reconnect case so must check |
4110 | * need_reconnect flag here. The caller will also clear |
4111 | * need_reconnect when tcon was successful but needed to be |
4112 | * cleared earlier in the case of unix extensions reconnect |
4113 | */ |
4114 | if (tcon->need_reconnect && tcon->unix_ext) { |
4115 | cifs_dbg(FYI, "resetting caps for %s\n" , tcon->tree_name); |
4116 | tcon->need_reconnect = false; |
4117 | reset_cifs_unix_caps(xid, tcon, NULL, NULL); |
4118 | } |
4119 | } |
4120 | cifs_buf_release(smb_buffer); |
4121 | return rc; |
4122 | } |
4123 | #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ |
4124 | |
4125 | static void delayed_free(struct rcu_head *p) |
4126 | { |
4127 | struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu); |
4128 | |
4129 | unload_nls(cifs_sb->local_nls); |
4130 | smb3_cleanup_fs_context(ctx: cifs_sb->ctx); |
4131 | kfree(objp: cifs_sb); |
4132 | } |
4133 | |
4134 | void |
4135 | cifs_umount(struct cifs_sb_info *cifs_sb) |
4136 | { |
4137 | struct rb_root *root = &cifs_sb->tlink_tree; |
4138 | struct rb_node *node; |
4139 | struct tcon_link *tlink; |
4140 | struct cifs_tcon *tcon = NULL; |
4141 | |
4142 | cancel_delayed_work_sync(dwork: &cifs_sb->prune_tlinks); |
4143 | |
4144 | if (cifs_sb->master_tlink) { |
4145 | tcon = cifs_sb->master_tlink->tl_tcon; |
4146 | if (tcon) { |
4147 | spin_lock(lock: &tcon->sb_list_lock); |
4148 | list_del_init(entry: &cifs_sb->tcon_sb_link); |
4149 | spin_unlock(lock: &tcon->sb_list_lock); |
4150 | } |
4151 | } |
4152 | |
4153 | spin_lock(lock: &cifs_sb->tlink_tree_lock); |
4154 | while ((node = rb_first(root))) { |
4155 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); |
4156 | cifs_get_tlink(tlink); |
4157 | clear_bit(TCON_LINK_IN_TREE, addr: &tlink->tl_flags); |
4158 | rb_erase(node, root); |
4159 | |
4160 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
4161 | cifs_put_tlink(tlink); |
4162 | spin_lock(lock: &cifs_sb->tlink_tree_lock); |
4163 | } |
4164 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
4165 | |
4166 | kfree(objp: cifs_sb->prepath); |
4167 | call_rcu(head: &cifs_sb->rcu, func: delayed_free); |
4168 | } |
4169 | |
4170 | int |
4171 | cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, |
4172 | struct TCP_Server_Info *server) |
4173 | { |
4174 | bool in_retry = false; |
4175 | int rc = 0; |
4176 | |
4177 | if (!server->ops->need_neg || !server->ops->negotiate) |
4178 | return -ENOSYS; |
4179 | |
4180 | retry: |
4181 | /* only send once per connect */ |
4182 | spin_lock(lock: &server->srv_lock); |
4183 | if (server->tcpStatus != CifsGood && |
4184 | server->tcpStatus != CifsNew && |
4185 | server->tcpStatus != CifsNeedNegotiate) { |
4186 | spin_unlock(lock: &server->srv_lock); |
4187 | return -EHOSTDOWN; |
4188 | } |
4189 | |
4190 | if (!server->ops->need_neg(server) && |
4191 | server->tcpStatus == CifsGood) { |
4192 | spin_unlock(lock: &server->srv_lock); |
4193 | return 0; |
4194 | } |
4195 | |
4196 | server->tcpStatus = CifsInNegotiate; |
4197 | spin_unlock(lock: &server->srv_lock); |
4198 | |
4199 | rc = server->ops->negotiate(xid, ses, server); |
4200 | if (rc == -EAGAIN) { |
4201 | /* Allow one retry attempt */ |
4202 | if (!in_retry) { |
4203 | in_retry = true; |
4204 | goto retry; |
4205 | } |
4206 | rc = -EHOSTDOWN; |
4207 | } |
4208 | if (rc == 0) { |
4209 | spin_lock(lock: &server->srv_lock); |
4210 | if (server->tcpStatus == CifsInNegotiate) |
4211 | server->tcpStatus = CifsGood; |
4212 | else |
4213 | rc = -EHOSTDOWN; |
4214 | spin_unlock(lock: &server->srv_lock); |
4215 | } else { |
4216 | spin_lock(lock: &server->srv_lock); |
4217 | if (server->tcpStatus == CifsInNegotiate) |
4218 | server->tcpStatus = CifsNeedNegotiate; |
4219 | spin_unlock(lock: &server->srv_lock); |
4220 | } |
4221 | |
4222 | return rc; |
4223 | } |
4224 | |
4225 | int |
4226 | cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, |
4227 | struct TCP_Server_Info *server, |
4228 | struct nls_table *nls_info) |
4229 | { |
4230 | int rc = 0; |
4231 | struct TCP_Server_Info *pserver = SERVER_IS_CHAN(server) ? server->primary_server : server; |
4232 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&pserver->dstaddr; |
4233 | struct sockaddr_in *addr = (struct sockaddr_in *)&pserver->dstaddr; |
4234 | bool is_binding = false; |
4235 | |
4236 | spin_lock(lock: &ses->ses_lock); |
4237 | cifs_dbg(FYI, "%s: channel connect bitmap: 0x%lx\n" , |
4238 | __func__, ses->chans_need_reconnect); |
4239 | |
4240 | if (ses->ses_status != SES_GOOD && |
4241 | ses->ses_status != SES_NEW && |
4242 | ses->ses_status != SES_NEED_RECON) { |
4243 | spin_unlock(lock: &ses->ses_lock); |
4244 | return -EHOSTDOWN; |
4245 | } |
4246 | |
4247 | /* only send once per connect */ |
4248 | spin_lock(lock: &ses->chan_lock); |
4249 | if (CIFS_ALL_CHANS_GOOD(ses)) { |
4250 | if (ses->ses_status == SES_NEED_RECON) |
4251 | ses->ses_status = SES_GOOD; |
4252 | spin_unlock(lock: &ses->chan_lock); |
4253 | spin_unlock(lock: &ses->ses_lock); |
4254 | return 0; |
4255 | } |
4256 | |
4257 | cifs_chan_set_in_reconnect(ses, server); |
4258 | is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses); |
4259 | spin_unlock(lock: &ses->chan_lock); |
4260 | |
4261 | if (!is_binding) { |
4262 | ses->ses_status = SES_IN_SETUP; |
4263 | |
4264 | /* force iface_list refresh */ |
4265 | ses->iface_last_update = 0; |
4266 | } |
4267 | spin_unlock(lock: &ses->ses_lock); |
4268 | |
4269 | /* update ses ip_addr only for primary chan */ |
4270 | if (server == pserver) { |
4271 | if (server->dstaddr.ss_family == AF_INET6) |
4272 | scnprintf(buf: ses->ip_addr, size: sizeof(ses->ip_addr), fmt: "%pI6" , &addr6->sin6_addr); |
4273 | else |
4274 | scnprintf(buf: ses->ip_addr, size: sizeof(ses->ip_addr), fmt: "%pI4" , &addr->sin_addr); |
4275 | } |
4276 | |
4277 | if (!is_binding) { |
4278 | ses->capabilities = server->capabilities; |
4279 | if (!linuxExtEnabled) |
4280 | ses->capabilities &= (~server->vals->cap_unix); |
4281 | |
4282 | /* |
4283 | * Check if the server supports specified encoding mode. |
4284 | * Zero value in vals->cap_unicode indidcates that chosen |
4285 | * protocol dialect does not support non-UNICODE mode. |
4286 | */ |
4287 | if (ses->unicode == 1 && server->vals->cap_unicode != 0 && |
4288 | !(server->capabilities & server->vals->cap_unicode)) { |
4289 | cifs_dbg(VFS, "Server does not support mounting in UNICODE mode\n" ); |
4290 | rc = -EOPNOTSUPP; |
4291 | } else if (ses->unicode == 0 && server->vals->cap_unicode == 0) { |
4292 | cifs_dbg(VFS, "Server does not support mounting in non-UNICODE mode\n" ); |
4293 | rc = -EOPNOTSUPP; |
4294 | } else if (ses->unicode == 0) { |
4295 | /* |
4296 | * When UNICODE mode was explicitly disabled then |
4297 | * do not announce client UNICODE capability. |
4298 | */ |
4299 | ses->capabilities &= (~server->vals->cap_unicode); |
4300 | } |
4301 | |
4302 | if (ses->auth_key.response) { |
4303 | cifs_dbg(FYI, "Free previous auth_key.response = %p\n" , |
4304 | ses->auth_key.response); |
4305 | kfree_sensitive(objp: ses->auth_key.response); |
4306 | ses->auth_key.response = NULL; |
4307 | ses->auth_key.len = 0; |
4308 | } |
4309 | } |
4310 | |
4311 | cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n" , |
4312 | server->sec_mode, server->capabilities, server->timeAdj); |
4313 | |
4314 | if (!rc) { |
4315 | if (server->ops->sess_setup) |
4316 | rc = server->ops->sess_setup(xid, ses, server, nls_info); |
4317 | else |
4318 | rc = -ENOSYS; |
4319 | } |
4320 | |
4321 | if (rc) { |
4322 | cifs_server_dbg(VFS, "Send error in SessSetup = %d\n" , rc); |
4323 | spin_lock(lock: &ses->ses_lock); |
4324 | if (ses->ses_status == SES_IN_SETUP) |
4325 | ses->ses_status = SES_NEED_RECON; |
4326 | spin_lock(lock: &ses->chan_lock); |
4327 | cifs_chan_clear_in_reconnect(ses, server); |
4328 | spin_unlock(lock: &ses->chan_lock); |
4329 | spin_unlock(lock: &ses->ses_lock); |
4330 | } else { |
4331 | spin_lock(lock: &ses->ses_lock); |
4332 | if (ses->ses_status == SES_IN_SETUP) |
4333 | ses->ses_status = SES_GOOD; |
4334 | spin_lock(lock: &ses->chan_lock); |
4335 | cifs_chan_clear_in_reconnect(ses, server); |
4336 | cifs_chan_clear_need_reconnect(ses, server); |
4337 | spin_unlock(lock: &ses->chan_lock); |
4338 | spin_unlock(lock: &ses->ses_lock); |
4339 | } |
4340 | |
4341 | return rc; |
4342 | } |
4343 | |
4344 | static int |
4345 | cifs_set_vol_auth(struct smb3_fs_context *ctx, struct cifs_ses *ses) |
4346 | { |
4347 | ctx->sectype = ses->sectype; |
4348 | |
4349 | /* krb5 is special, since we don't need username or pw */ |
4350 | if (ctx->sectype == Kerberos) |
4351 | return 0; |
4352 | |
4353 | return cifs_set_cifscreds(ctx, ses); |
4354 | } |
4355 | |
4356 | static struct cifs_tcon * |
4357 | cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) |
4358 | { |
4359 | int rc; |
4360 | struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb); |
4361 | struct cifs_ses *ses; |
4362 | struct cifs_tcon *tcon = NULL; |
4363 | struct smb3_fs_context *ctx; |
4364 | char *origin_fullpath = NULL; |
4365 | |
4366 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
4367 | if (ctx == NULL) |
4368 | return ERR_PTR(error: -ENOMEM); |
4369 | |
4370 | ctx->local_nls = cifs_sb->local_nls; |
4371 | ctx->linux_uid = fsuid; |
4372 | ctx->cred_uid = fsuid; |
4373 | ctx->UNC = master_tcon->tree_name; |
4374 | ctx->retry = master_tcon->retry; |
4375 | ctx->nocase = master_tcon->nocase; |
4376 | ctx->nohandlecache = master_tcon->nohandlecache; |
4377 | ctx->local_lease = master_tcon->local_lease; |
4378 | ctx->no_lease = master_tcon->no_lease; |
4379 | ctx->resilient = master_tcon->use_resilient; |
4380 | ctx->persistent = master_tcon->use_persistent; |
4381 | ctx->handle_timeout = master_tcon->handle_timeout; |
4382 | ctx->no_linux_ext = !master_tcon->unix_ext; |
4383 | ctx->linux_ext = master_tcon->posix_extensions; |
4384 | ctx->sectype = master_tcon->ses->sectype; |
4385 | ctx->sign = master_tcon->ses->sign; |
4386 | ctx->seal = master_tcon->seal; |
4387 | ctx->witness = master_tcon->use_witness; |
4388 | ctx->dfs_root_ses = master_tcon->ses->dfs_root_ses; |
4389 | ctx->unicode = master_tcon->ses->unicode; |
4390 | |
4391 | rc = cifs_set_vol_auth(ctx, ses: master_tcon->ses); |
4392 | if (rc) { |
4393 | tcon = ERR_PTR(error: rc); |
4394 | goto out; |
4395 | } |
4396 | |
4397 | /* get a reference for the same TCP session */ |
4398 | spin_lock(lock: &cifs_tcp_ses_lock); |
4399 | ++master_tcon->ses->server->srv_count; |
4400 | spin_unlock(lock: &cifs_tcp_ses_lock); |
4401 | |
4402 | ses = cifs_get_smb_ses(server: master_tcon->ses->server, ctx); |
4403 | if (IS_ERR(ptr: ses)) { |
4404 | tcon = ERR_CAST(ptr: ses); |
4405 | cifs_put_tcp_session(server: master_tcon->ses->server, from_reconnect: 0); |
4406 | goto out; |
4407 | } |
4408 | |
4409 | #ifdef CONFIG_CIFS_DFS_UPCALL |
4410 | spin_lock(lock: &master_tcon->tc_lock); |
4411 | if (master_tcon->origin_fullpath) { |
4412 | spin_unlock(lock: &master_tcon->tc_lock); |
4413 | origin_fullpath = dfs_get_path(cifs_sb, path: cifs_sb->ctx->source); |
4414 | if (IS_ERR(ptr: origin_fullpath)) { |
4415 | tcon = ERR_CAST(ptr: origin_fullpath); |
4416 | origin_fullpath = NULL; |
4417 | cifs_put_smb_ses(ses); |
4418 | goto out; |
4419 | } |
4420 | } else { |
4421 | spin_unlock(lock: &master_tcon->tc_lock); |
4422 | } |
4423 | #endif |
4424 | |
4425 | tcon = cifs_get_tcon(ses, ctx); |
4426 | if (IS_ERR(ptr: tcon)) { |
4427 | cifs_put_smb_ses(ses); |
4428 | goto out; |
4429 | } |
4430 | |
4431 | #ifdef CONFIG_CIFS_DFS_UPCALL |
4432 | if (origin_fullpath) { |
4433 | spin_lock(lock: &tcon->tc_lock); |
4434 | tcon->origin_fullpath = origin_fullpath; |
4435 | spin_unlock(lock: &tcon->tc_lock); |
4436 | origin_fullpath = NULL; |
4437 | queue_delayed_work(wq: dfscache_wq, dwork: &tcon->dfs_cache_work, |
4438 | delay: dfs_cache_get_ttl() * HZ); |
4439 | } |
4440 | #endif |
4441 | |
4442 | #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY |
4443 | if (cap_unix(ses)) |
4444 | reset_cifs_unix_caps(xid: 0, tcon, NULL, ctx); |
4445 | #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ |
4446 | |
4447 | out: |
4448 | kfree(objp: ctx->username); |
4449 | kfree_sensitive(objp: ctx->password); |
4450 | kfree(objp: origin_fullpath); |
4451 | kfree(objp: ctx); |
4452 | |
4453 | return tcon; |
4454 | } |
4455 | |
4456 | struct cifs_tcon * |
4457 | cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) |
4458 | { |
4459 | return tlink_tcon(tlink: cifs_sb_master_tlink(cifs_sb)); |
4460 | } |
4461 | |
4462 | /* find and return a tlink with given uid */ |
4463 | static struct tcon_link * |
4464 | tlink_rb_search(struct rb_root *root, kuid_t uid) |
4465 | { |
4466 | struct rb_node *node = root->rb_node; |
4467 | struct tcon_link *tlink; |
4468 | |
4469 | while (node) { |
4470 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); |
4471 | |
4472 | if (uid_gt(left: tlink->tl_uid, right: uid)) |
4473 | node = node->rb_left; |
4474 | else if (uid_lt(left: tlink->tl_uid, right: uid)) |
4475 | node = node->rb_right; |
4476 | else |
4477 | return tlink; |
4478 | } |
4479 | return NULL; |
4480 | } |
4481 | |
4482 | /* insert a tcon_link into the tree */ |
4483 | static void |
4484 | tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) |
4485 | { |
4486 | struct rb_node **new = &(root->rb_node), *parent = NULL; |
4487 | struct tcon_link *tlink; |
4488 | |
4489 | while (*new) { |
4490 | tlink = rb_entry(*new, struct tcon_link, tl_rbnode); |
4491 | parent = *new; |
4492 | |
4493 | if (uid_gt(left: tlink->tl_uid, right: new_tlink->tl_uid)) |
4494 | new = &((*new)->rb_left); |
4495 | else |
4496 | new = &((*new)->rb_right); |
4497 | } |
4498 | |
4499 | rb_link_node(node: &new_tlink->tl_rbnode, parent, rb_link: new); |
4500 | rb_insert_color(&new_tlink->tl_rbnode, root); |
4501 | } |
4502 | |
4503 | /* |
4504 | * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the |
4505 | * current task. |
4506 | * |
4507 | * If the superblock doesn't refer to a multiuser mount, then just return |
4508 | * the master tcon for the mount. |
4509 | * |
4510 | * First, search the rbtree for an existing tcon for this fsuid. If one |
4511 | * exists, then check to see if it's pending construction. If it is then wait |
4512 | * for construction to complete. Once it's no longer pending, check to see if |
4513 | * it failed and either return an error or retry construction, depending on |
4514 | * the timeout. |
4515 | * |
4516 | * If one doesn't exist then insert a new tcon_link struct into the tree and |
4517 | * try to construct a new one. |
4518 | * |
4519 | * REMEMBER to call cifs_put_tlink() after successful calls to cifs_sb_tlink, |
4520 | * to avoid refcount issues |
4521 | */ |
4522 | struct tcon_link * |
4523 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) |
4524 | { |
4525 | struct tcon_link *tlink, *newtlink; |
4526 | kuid_t fsuid = current_fsuid(); |
4527 | int err; |
4528 | |
4529 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
4530 | return cifs_get_tlink(tlink: cifs_sb_master_tlink(cifs_sb)); |
4531 | |
4532 | spin_lock(lock: &cifs_sb->tlink_tree_lock); |
4533 | tlink = tlink_rb_search(root: &cifs_sb->tlink_tree, uid: fsuid); |
4534 | if (tlink) |
4535 | cifs_get_tlink(tlink); |
4536 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
4537 | |
4538 | if (tlink == NULL) { |
4539 | newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); |
4540 | if (newtlink == NULL) |
4541 | return ERR_PTR(error: -ENOMEM); |
4542 | newtlink->tl_uid = fsuid; |
4543 | newtlink->tl_tcon = ERR_PTR(error: -EACCES); |
4544 | set_bit(TCON_LINK_PENDING, addr: &newtlink->tl_flags); |
4545 | set_bit(TCON_LINK_IN_TREE, addr: &newtlink->tl_flags); |
4546 | cifs_get_tlink(tlink: newtlink); |
4547 | |
4548 | spin_lock(lock: &cifs_sb->tlink_tree_lock); |
4549 | /* was one inserted after previous search? */ |
4550 | tlink = tlink_rb_search(root: &cifs_sb->tlink_tree, uid: fsuid); |
4551 | if (tlink) { |
4552 | cifs_get_tlink(tlink); |
4553 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
4554 | kfree(objp: newtlink); |
4555 | goto wait_for_construction; |
4556 | } |
4557 | tlink = newtlink; |
4558 | tlink_rb_insert(root: &cifs_sb->tlink_tree, new_tlink: tlink); |
4559 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
4560 | } else { |
4561 | wait_for_construction: |
4562 | err = wait_on_bit(word: &tlink->tl_flags, TCON_LINK_PENDING, |
4563 | TASK_INTERRUPTIBLE); |
4564 | if (err) { |
4565 | cifs_put_tlink(tlink); |
4566 | return ERR_PTR(error: -ERESTARTSYS); |
4567 | } |
4568 | |
4569 | /* if it's good, return it */ |
4570 | if (!IS_ERR(ptr: tlink->tl_tcon)) |
4571 | return tlink; |
4572 | |
4573 | /* return error if we tried this already recently */ |
4574 | if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) { |
4575 | err = PTR_ERR(ptr: tlink->tl_tcon); |
4576 | cifs_put_tlink(tlink); |
4577 | return ERR_PTR(error: err); |
4578 | } |
4579 | |
4580 | if (test_and_set_bit(TCON_LINK_PENDING, addr: &tlink->tl_flags)) |
4581 | goto wait_for_construction; |
4582 | } |
4583 | |
4584 | tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid); |
4585 | clear_bit(TCON_LINK_PENDING, addr: &tlink->tl_flags); |
4586 | wake_up_bit(word: &tlink->tl_flags, TCON_LINK_PENDING); |
4587 | |
4588 | if (IS_ERR(ptr: tlink->tl_tcon)) { |
4589 | err = PTR_ERR(ptr: tlink->tl_tcon); |
4590 | if (err == -ENOKEY) |
4591 | err = -EACCES; |
4592 | cifs_put_tlink(tlink); |
4593 | return ERR_PTR(error: err); |
4594 | } |
4595 | |
4596 | return tlink; |
4597 | } |
4598 | |
4599 | /* |
4600 | * periodic workqueue job that scans tcon_tree for a superblock and closes |
4601 | * out tcons. |
4602 | */ |
4603 | static void |
4604 | cifs_prune_tlinks(struct work_struct *work) |
4605 | { |
4606 | struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, |
4607 | prune_tlinks.work); |
4608 | struct rb_root *root = &cifs_sb->tlink_tree; |
4609 | struct rb_node *node; |
4610 | struct rb_node *tmp; |
4611 | struct tcon_link *tlink; |
4612 | |
4613 | /* |
4614 | * Because we drop the spinlock in the loop in order to put the tlink |
4615 | * it's not guarded against removal of links from the tree. The only |
4616 | * places that remove entries from the tree are this function and |
4617 | * umounts. Because this function is non-reentrant and is canceled |
4618 | * before umount can proceed, this is safe. |
4619 | */ |
4620 | spin_lock(lock: &cifs_sb->tlink_tree_lock); |
4621 | node = rb_first(root); |
4622 | while (node != NULL) { |
4623 | tmp = node; |
4624 | node = rb_next(tmp); |
4625 | tlink = rb_entry(tmp, struct tcon_link, tl_rbnode); |
4626 | |
4627 | if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || |
4628 | atomic_read(v: &tlink->tl_count) != 0 || |
4629 | time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) |
4630 | continue; |
4631 | |
4632 | cifs_get_tlink(tlink); |
4633 | clear_bit(TCON_LINK_IN_TREE, addr: &tlink->tl_flags); |
4634 | rb_erase(tmp, root); |
4635 | |
4636 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
4637 | cifs_put_tlink(tlink); |
4638 | spin_lock(lock: &cifs_sb->tlink_tree_lock); |
4639 | } |
4640 | spin_unlock(lock: &cifs_sb->tlink_tree_lock); |
4641 | |
4642 | queue_delayed_work(wq: cifsiod_wq, dwork: &cifs_sb->prune_tlinks, |
4643 | TLINK_IDLE_EXPIRE); |
4644 | } |
4645 | |
4646 | #ifndef CONFIG_CIFS_DFS_UPCALL |
4647 | int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon) |
4648 | { |
4649 | const struct smb_version_operations *ops = tcon->ses->server->ops; |
4650 | int rc; |
4651 | |
4652 | /* only send once per connect */ |
4653 | spin_lock(&tcon->tc_lock); |
4654 | |
4655 | /* if tcon is marked for needing reconnect, update state */ |
4656 | if (tcon->need_reconnect) |
4657 | tcon->status = TID_NEED_TCON; |
4658 | |
4659 | if (tcon->status == TID_GOOD) { |
4660 | spin_unlock(&tcon->tc_lock); |
4661 | return 0; |
4662 | } |
4663 | |
4664 | if (tcon->status != TID_NEW && |
4665 | tcon->status != TID_NEED_TCON) { |
4666 | spin_unlock(&tcon->tc_lock); |
4667 | return -EHOSTDOWN; |
4668 | } |
4669 | |
4670 | tcon->status = TID_IN_TCON; |
4671 | spin_unlock(&tcon->tc_lock); |
4672 | |
4673 | rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, |
4674 | tcon, tcon->ses->local_nls); |
4675 | if (rc) { |
4676 | spin_lock(&tcon->tc_lock); |
4677 | if (tcon->status == TID_IN_TCON) |
4678 | tcon->status = TID_NEED_TCON; |
4679 | spin_unlock(&tcon->tc_lock); |
4680 | } else { |
4681 | spin_lock(&tcon->tc_lock); |
4682 | if (tcon->status == TID_IN_TCON) |
4683 | tcon->status = TID_GOOD; |
4684 | tcon->need_reconnect = false; |
4685 | spin_unlock(&tcon->tc_lock); |
4686 | } |
4687 | |
4688 | return rc; |
4689 | } |
4690 | #endif |
4691 | |