]>
Commit | Line | Data |
---|---|---|
2dc7e1c0 PS |
1 | /* |
2 | * fs/cifs/smb2transport.c | |
3 | * | |
4 | * Copyright (C) International Business Machines Corp., 2002, 2011 | |
5 | * Etersoft, 2012 | |
6 | * Author(s): Steve French ([email protected]) | |
7 | * Jeremy Allison ([email protected]) 2006 | |
8 | * Pavel Shilovsky ([email protected]) 2012 | |
9 | * | |
10 | * This library is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU Lesser General Public License as published | |
12 | * by the Free Software Foundation; either version 2.1 of the License, or | |
13 | * (at your option) any later version. | |
14 | * | |
15 | * This library is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | |
18 | * the GNU Lesser General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU Lesser General Public License | |
21 | * along with this library; if not, write to the Free Software | |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 | */ | |
24 | ||
25 | #include <linux/fs.h> | |
26 | #include <linux/list.h> | |
27 | #include <linux/wait.h> | |
28 | #include <linux/net.h> | |
29 | #include <linux/delay.h> | |
30 | #include <linux/uaccess.h> | |
31 | #include <asm/processor.h> | |
32 | #include <linux/mempool.h> | |
33 | #include "smb2pdu.h" | |
34 | #include "cifsglob.h" | |
35 | #include "cifsproto.h" | |
36 | #include "smb2proto.h" | |
37 | #include "cifs_debug.h" | |
38 | #include "smb2status.h" | |
39 | ||
40 | /* | |
41 | * Set message id for the request. Should be called after wait_for_free_request | |
42 | * and when srv_mutex is held. | |
43 | */ | |
44 | static inline void | |
45 | smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr) | |
46 | { | |
47 | hdr->MessageId = get_next_mid(server); | |
48 | } | |
49 | ||
50 | static struct mid_q_entry * | |
51 | smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer, | |
52 | struct TCP_Server_Info *server) | |
53 | { | |
54 | struct mid_q_entry *temp; | |
55 | ||
56 | if (server == NULL) { | |
57 | cERROR(1, "Null TCP session in smb2_mid_entry_alloc"); | |
58 | return NULL; | |
59 | } | |
60 | ||
61 | temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS); | |
62 | if (temp == NULL) | |
63 | return temp; | |
64 | else { | |
65 | memset(temp, 0, sizeof(struct mid_q_entry)); | |
66 | temp->mid = smb_buffer->MessageId; /* always LE */ | |
67 | temp->pid = current->pid; | |
68 | temp->command = smb_buffer->Command; /* Always LE */ | |
69 | temp->when_alloc = jiffies; | |
70 | temp->server = server; | |
71 | ||
72 | /* | |
73 | * The default is for the mid to be synchronous, so the | |
74 | * default callback just wakes up the current task. | |
75 | */ | |
76 | temp->callback = cifs_wake_up_task; | |
77 | temp->callback_data = current; | |
78 | } | |
79 | ||
80 | atomic_inc(&midCount); | |
81 | temp->mid_state = MID_REQUEST_ALLOCATED; | |
82 | return temp; | |
83 | } | |
84 | ||
85 | static int | |
86 | smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf, | |
87 | struct mid_q_entry **mid) | |
88 | { | |
89 | if (ses->server->tcpStatus == CifsExiting) | |
90 | return -ENOENT; | |
91 | ||
92 | if (ses->server->tcpStatus == CifsNeedReconnect) { | |
93 | cFYI(1, "tcp session dead - return to caller to retry"); | |
94 | return -EAGAIN; | |
95 | } | |
96 | ||
97 | if (ses->status != CifsGood) { | |
98 | /* check if SMB2 session is bad because we are setting it up */ | |
99 | if ((buf->Command != SMB2_SESSION_SETUP) && | |
100 | (buf->Command != SMB2_NEGOTIATE)) | |
101 | return -EAGAIN; | |
102 | /* else ok - we are setting up session */ | |
103 | } | |
104 | *mid = smb2_mid_entry_alloc(buf, ses->server); | |
105 | if (*mid == NULL) | |
106 | return -ENOMEM; | |
107 | spin_lock(&GlobalMid_Lock); | |
108 | list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q); | |
109 | spin_unlock(&GlobalMid_Lock); | |
110 | return 0; | |
111 | } | |
112 | ||
113 | int | |
114 | smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, | |
115 | bool log_error) | |
116 | { | |
117 | unsigned int len = get_rfc1002_length(mid->resp_buf); | |
118 | ||
119 | dump_smb(mid->resp_buf, min_t(u32, 80, len)); | |
120 | /* convert the length into a more usable form */ | |
121 | /* BB - uncomment with SMB2 signing implementation */ | |
122 | /* if ((len > 24) && | |
123 | (server->sec_mode & (SECMODE_SIGN_REQUIRED|SECMODE_SIGN_ENABLED))) { | |
124 | if (smb2_verify_signature(mid->resp_buf, server)) | |
125 | cERROR(1, "Unexpected SMB signature"); | |
126 | } */ | |
127 | ||
128 | return map_smb2_to_linux_error(mid->resp_buf, log_error); | |
129 | } | |
130 | ||
131 | int | |
132 | smb2_setup_request(struct cifs_ses *ses, struct kvec *iov, | |
133 | unsigned int nvec, struct mid_q_entry **ret_mid) | |
134 | { | |
135 | int rc; | |
136 | struct smb2_hdr *hdr = (struct smb2_hdr *)iov[0].iov_base; | |
137 | struct mid_q_entry *mid; | |
138 | ||
139 | smb2_seq_num_into_buf(ses->server, hdr); | |
140 | ||
141 | rc = smb2_get_mid_entry(ses, hdr, &mid); | |
142 | if (rc) | |
143 | return rc; | |
144 | /* rc = smb2_sign_smb2(iov, nvec, ses->server); | |
145 | if (rc) | |
146 | delete_mid(mid); */ | |
147 | *ret_mid = mid; | |
148 | return rc; | |
149 | } | |
150 | ||
c95b8eed PS |
151 | int |
152 | smb2_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov, | |
153 | unsigned int nvec, struct mid_q_entry **ret_mid) | |
154 | { | |
155 | int rc = 0; | |
156 | struct smb2_hdr *hdr = (struct smb2_hdr *)iov[0].iov_base; | |
157 | struct mid_q_entry *mid; | |
158 | ||
159 | smb2_seq_num_into_buf(server, hdr); | |
160 | ||
161 | mid = smb2_mid_entry_alloc(hdr, server); | |
162 | if (mid == NULL) | |
163 | return -ENOMEM; | |
164 | ||
165 | /* rc = smb2_sign_smb2(iov, nvec, server); | |
166 | if (rc) { | |
167 | DeleteMidQEntry(mid); | |
168 | return rc; | |
169 | }*/ | |
170 | *ret_mid = mid; | |
171 | return rc; | |
172 | } |