Commit ee2c9258501f83d3ed0fd09ce5df1cec53312cf0

Authored by Shirish Pargaonkar
Committed by Steve French
1 parent d39454ffe4

cifs: More crypto cleanup (try #2)

Replaced md4 hashing function local to cifs module with kernel crypto APIs.
As a result, md4 hashing function and its supporting functions in
file md4.c are not needed anymore.

Cleaned up function declarations, removed forward function declarations,
and removed a header file that is being deleted from being included.

Verified that sec=ntlm/i, sec=ntlmv2/i, and sec=ntlmssp/i work correctly.

Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>

Showing 9 changed files with 97 additions and 286 deletions Inline Diff

1 # 1 #
2 # Makefile for Linux CIFS VFS client 2 # Makefile for Linux CIFS VFS client
3 # 3 #
4 obj-$(CONFIG_CIFS) += cifs.o 4 obj-$(CONFIG_CIFS) += cifs.o
5 5
6 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ 6 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ 7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
8 md4.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ 8 cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
9 readdir.o ioctl.o sess.o export.o 9 readdir.o ioctl.o sess.o export.o
10 10
11 cifs-$(CONFIG_CIFS_ACL) += cifsacl.o 11 cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
12 12
13 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o 13 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
14 14
15 cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o 15 cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
16 16
17 cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o 17 cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
18 18
fs/cifs/cifsencrypt.c
1 /* 1 /*
2 * fs/cifs/cifsencrypt.c 2 * fs/cifs/cifsencrypt.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2005,2006 4 * Copyright (C) International Business Machines Corp., 2005,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published 8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or 9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details. 15 * the GNU Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22 #include <linux/fs.h> 22 #include <linux/fs.h>
23 #include <linux/slab.h> 23 #include <linux/slab.h>
24 #include "cifspdu.h" 24 #include "cifspdu.h"
25 #include "cifsglob.h" 25 #include "cifsglob.h"
26 #include "cifs_debug.h" 26 #include "cifs_debug.h"
27 #include "cifs_unicode.h" 27 #include "cifs_unicode.h"
28 #include "cifsproto.h" 28 #include "cifsproto.h"
29 #include "ntlmssp.h" 29 #include "ntlmssp.h"
30 #include <linux/ctype.h> 30 #include <linux/ctype.h>
31 #include <linux/random.h> 31 #include <linux/random.h>
32 32
33 /* Calculate and return the CIFS signature based on the mac key and SMB PDU */ 33 /* Calculate and return the CIFS signature based on the mac key and SMB PDU */
34 /* the 16 byte signature must be allocated by the caller */ 34 /* the 16 byte signature must be allocated by the caller */
35 /* Note we only use the 1st eight bytes */ 35 /* Note we only use the 1st eight bytes */
36 /* Note that the smb header signature field on input contains the 36 /* Note that the smb header signature field on input contains the
37 sequence number before this function is called */ 37 sequence number before this function is called */
38 38
39 extern void mdfour(unsigned char *out, unsigned char *in, int n);
40 extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
41 extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
42 unsigned char *p24);
43
44 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 39 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
45 struct TCP_Server_Info *server, char *signature) 40 struct TCP_Server_Info *server, char *signature)
46 { 41 {
47 int rc; 42 int rc;
48 43
49 if (cifs_pdu == NULL || signature == NULL || server == NULL) 44 if (cifs_pdu == NULL || signature == NULL || server == NULL)
50 return -EINVAL; 45 return -EINVAL;
51 46
52 if (!server->secmech.sdescmd5) { 47 if (!server->secmech.sdescmd5) {
53 cERROR(1, "%s: Can't generate signature\n", __func__); 48 cERROR(1, "%s: Can't generate signature\n", __func__);
54 return -1; 49 return -1;
55 } 50 }
56 51
57 rc = crypto_shash_init(&server->secmech.sdescmd5->shash); 52 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
58 if (rc) { 53 if (rc) {
59 cERROR(1, "%s: Oould not init md5\n", __func__); 54 cERROR(1, "%s: Oould not init md5\n", __func__);
60 return rc; 55 return rc;
61 } 56 }
62 57
63 crypto_shash_update(&server->secmech.sdescmd5->shash, 58 crypto_shash_update(&server->secmech.sdescmd5->shash,
64 server->session_key.response, server->session_key.len); 59 server->session_key.response, server->session_key.len);
65 60
66 crypto_shash_update(&server->secmech.sdescmd5->shash, 61 crypto_shash_update(&server->secmech.sdescmd5->shash,
67 cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 62 cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
68 63
69 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature); 64 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
70 65
71 return 0; 66 return 0;
72 } 67 }
73 68
74 /* must be called with server->srv_mutex held */ 69 /* must be called with server->srv_mutex held */
75 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 70 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
76 __u32 *pexpected_response_sequence_number) 71 __u32 *pexpected_response_sequence_number)
77 { 72 {
78 int rc = 0; 73 int rc = 0;
79 char smb_signature[20]; 74 char smb_signature[20];
80 75
81 if ((cifs_pdu == NULL) || (server == NULL)) 76 if ((cifs_pdu == NULL) || (server == NULL))
82 return -EINVAL; 77 return -EINVAL;
83 78
84 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 79 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
85 return rc; 80 return rc;
86 81
87 cifs_pdu->Signature.Sequence.SequenceNumber = 82 cifs_pdu->Signature.Sequence.SequenceNumber =
88 cpu_to_le32(server->sequence_number); 83 cpu_to_le32(server->sequence_number);
89 cifs_pdu->Signature.Sequence.Reserved = 0; 84 cifs_pdu->Signature.Sequence.Reserved = 0;
90 85
91 *pexpected_response_sequence_number = server->sequence_number++; 86 *pexpected_response_sequence_number = server->sequence_number++;
92 server->sequence_number++; 87 server->sequence_number++;
93 88
94 rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); 89 rc = cifs_calculate_signature(cifs_pdu, server, smb_signature);
95 if (rc) 90 if (rc)
96 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 91 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
97 else 92 else
98 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 93 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
99 94
100 return rc; 95 return rc;
101 } 96 }
102 97
103 static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 98 static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
104 struct TCP_Server_Info *server, char *signature) 99 struct TCP_Server_Info *server, char *signature)
105 { 100 {
106 int i; 101 int i;
107 int rc; 102 int rc;
108 103
109 if (iov == NULL || signature == NULL || server == NULL) 104 if (iov == NULL || signature == NULL || server == NULL)
110 return -EINVAL; 105 return -EINVAL;
111 106
112 if (!server->secmech.sdescmd5) { 107 if (!server->secmech.sdescmd5) {
113 cERROR(1, "%s: Can't generate signature\n", __func__); 108 cERROR(1, "%s: Can't generate signature\n", __func__);
114 return -1; 109 return -1;
115 } 110 }
116 111
117 rc = crypto_shash_init(&server->secmech.sdescmd5->shash); 112 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
118 if (rc) { 113 if (rc) {
119 cERROR(1, "%s: Oould not init md5\n", __func__); 114 cERROR(1, "%s: Oould not init md5\n", __func__);
120 return rc; 115 return rc;
121 } 116 }
122 117
123 crypto_shash_update(&server->secmech.sdescmd5->shash, 118 crypto_shash_update(&server->secmech.sdescmd5->shash,
124 server->session_key.response, server->session_key.len); 119 server->session_key.response, server->session_key.len);
125 120
126 for (i = 0; i < n_vec; i++) { 121 for (i = 0; i < n_vec; i++) {
127 if (iov[i].iov_len == 0) 122 if (iov[i].iov_len == 0)
128 continue; 123 continue;
129 if (iov[i].iov_base == NULL) { 124 if (iov[i].iov_base == NULL) {
130 cERROR(1, "null iovec entry"); 125 cERROR(1, "null iovec entry");
131 return -EIO; 126 return -EIO;
132 } 127 }
133 /* The first entry includes a length field (which does not get 128 /* The first entry includes a length field (which does not get
134 signed that occupies the first 4 bytes before the header */ 129 signed that occupies the first 4 bytes before the header */
135 if (i == 0) { 130 if (i == 0) {
136 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 131 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
137 break; /* nothing to sign or corrupt header */ 132 break; /* nothing to sign or corrupt header */
138 crypto_shash_update(&server->secmech.sdescmd5->shash, 133 crypto_shash_update(&server->secmech.sdescmd5->shash,
139 iov[i].iov_base + 4, iov[i].iov_len - 4); 134 iov[i].iov_base + 4, iov[i].iov_len - 4);
140 } else 135 } else
141 crypto_shash_update(&server->secmech.sdescmd5->shash, 136 crypto_shash_update(&server->secmech.sdescmd5->shash,
142 iov[i].iov_base, iov[i].iov_len); 137 iov[i].iov_base, iov[i].iov_len);
143 } 138 }
144 139
145 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature); 140 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
146 141
147 return rc; 142 return rc;
148 } 143 }
149 144
150 /* must be called with server->srv_mutex held */ 145 /* must be called with server->srv_mutex held */
151 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 146 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
152 __u32 *pexpected_response_sequence_number) 147 __u32 *pexpected_response_sequence_number)
153 { 148 {
154 int rc = 0; 149 int rc = 0;
155 char smb_signature[20]; 150 char smb_signature[20];
156 struct smb_hdr *cifs_pdu = iov[0].iov_base; 151 struct smb_hdr *cifs_pdu = iov[0].iov_base;
157 152
158 if ((cifs_pdu == NULL) || (server == NULL)) 153 if ((cifs_pdu == NULL) || (server == NULL))
159 return -EINVAL; 154 return -EINVAL;
160 155
161 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 156 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
162 return rc; 157 return rc;
163 158
164 cifs_pdu->Signature.Sequence.SequenceNumber = 159 cifs_pdu->Signature.Sequence.SequenceNumber =
165 cpu_to_le32(server->sequence_number); 160 cpu_to_le32(server->sequence_number);
166 cifs_pdu->Signature.Sequence.Reserved = 0; 161 cifs_pdu->Signature.Sequence.Reserved = 0;
167 162
168 *pexpected_response_sequence_number = server->sequence_number++; 163 *pexpected_response_sequence_number = server->sequence_number++;
169 server->sequence_number++; 164 server->sequence_number++;
170 165
171 rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); 166 rc = cifs_calc_signature2(iov, n_vec, server, smb_signature);
172 if (rc) 167 if (rc)
173 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 168 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
174 else 169 else
175 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 170 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
176 171
177 return rc; 172 return rc;
178 } 173 }
179 174
180 int cifs_verify_signature(struct smb_hdr *cifs_pdu, 175 int cifs_verify_signature(struct smb_hdr *cifs_pdu,
181 struct TCP_Server_Info *server, 176 struct TCP_Server_Info *server,
182 __u32 expected_sequence_number) 177 __u32 expected_sequence_number)
183 { 178 {
184 unsigned int rc; 179 unsigned int rc;
185 char server_response_sig[8]; 180 char server_response_sig[8];
186 char what_we_think_sig_should_be[20]; 181 char what_we_think_sig_should_be[20];
187 182
188 if (cifs_pdu == NULL || server == NULL) 183 if (cifs_pdu == NULL || server == NULL)
189 return -EINVAL; 184 return -EINVAL;
190 185
191 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) 186 if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
192 return 0; 187 return 0;
193 188
194 if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { 189 if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
195 struct smb_com_lock_req *pSMB = 190 struct smb_com_lock_req *pSMB =
196 (struct smb_com_lock_req *)cifs_pdu; 191 (struct smb_com_lock_req *)cifs_pdu;
197 if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE) 192 if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
198 return 0; 193 return 0;
199 } 194 }
200 195
201 /* BB what if signatures are supposed to be on for session but 196 /* BB what if signatures are supposed to be on for session but
202 server does not send one? BB */ 197 server does not send one? BB */
203 198
204 /* Do not need to verify session setups with signature "BSRSPYL " */ 199 /* Do not need to verify session setups with signature "BSRSPYL " */
205 if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0) 200 if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
206 cFYI(1, "dummy signature received for smb command 0x%x", 201 cFYI(1, "dummy signature received for smb command 0x%x",
207 cifs_pdu->Command); 202 cifs_pdu->Command);
208 203
209 /* save off the origiginal signature so we can modify the smb and check 204 /* save off the origiginal signature so we can modify the smb and check
210 its signature against what the server sent */ 205 its signature against what the server sent */
211 memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8); 206 memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
212 207
213 cifs_pdu->Signature.Sequence.SequenceNumber = 208 cifs_pdu->Signature.Sequence.SequenceNumber =
214 cpu_to_le32(expected_sequence_number); 209 cpu_to_le32(expected_sequence_number);
215 cifs_pdu->Signature.Sequence.Reserved = 0; 210 cifs_pdu->Signature.Sequence.Reserved = 0;
216 211
217 rc = cifs_calculate_signature(cifs_pdu, server, 212 rc = cifs_calculate_signature(cifs_pdu, server,
218 what_we_think_sig_should_be); 213 what_we_think_sig_should_be);
219 214
220 if (rc) 215 if (rc)
221 return rc; 216 return rc;
222 217
223 /* cifs_dump_mem("what we think it should be: ", 218 /* cifs_dump_mem("what we think it should be: ",
224 what_we_think_sig_should_be, 16); */ 219 what_we_think_sig_should_be, 16); */
225 220
226 if (memcmp(server_response_sig, what_we_think_sig_should_be, 8)) 221 if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
227 return -EACCES; 222 return -EACCES;
228 else 223 else
229 return 0; 224 return 0;
230 225
231 } 226 }
232 227
233 /* first calculate 24 bytes ntlm response and then 16 byte session key */ 228 /* first calculate 24 bytes ntlm response and then 16 byte session key */
234 int setup_ntlm_response(struct cifsSesInfo *ses) 229 int setup_ntlm_response(struct cifsSesInfo *ses)
235 { 230 {
231 int rc = 0;
236 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; 232 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
237 char temp_key[CIFS_SESS_KEY_SIZE]; 233 char temp_key[CIFS_SESS_KEY_SIZE];
238 234
239 if (!ses) 235 if (!ses)
240 return -EINVAL; 236 return -EINVAL;
241 237
242 ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL); 238 ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
243 if (!ses->auth_key.response) { 239 if (!ses->auth_key.response) {
244 cERROR(1, "NTLM can't allocate (%u bytes) memory", temp_len); 240 cERROR(1, "NTLM can't allocate (%u bytes) memory", temp_len);
245 return -ENOMEM; 241 return -ENOMEM;
246 } 242 }
247 ses->auth_key.len = temp_len; 243 ses->auth_key.len = temp_len;
248 244
249 SMBNTencrypt(ses->password, ses->server->cryptkey, 245 rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
250 ses->auth_key.response + CIFS_SESS_KEY_SIZE); 246 ses->auth_key.response + CIFS_SESS_KEY_SIZE);
247 if (rc) {
248 cFYI(1, "%s Can't generate NTLM response, error: %d",
249 __func__, rc);
250 return rc;
251 }
251 252
252 E_md4hash(ses->password, temp_key); 253 rc = E_md4hash(ses->password, temp_key);
253 mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE); 254 if (rc) {
255 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
256 return rc;
257 }
254 258
255 return 0; 259 rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
260 if (rc)
261 cFYI(1, "%s Can't generate NTLM session key, error: %d",
262 __func__, rc);
263
264 return rc;
256 } 265 }
257 266
258 #ifdef CONFIG_CIFS_WEAK_PW_HASH 267 #ifdef CONFIG_CIFS_WEAK_PW_HASH
259 void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, 268 void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
260 char *lnm_session_key) 269 char *lnm_session_key)
261 { 270 {
262 int i; 271 int i;
263 char password_with_pad[CIFS_ENCPWD_SIZE]; 272 char password_with_pad[CIFS_ENCPWD_SIZE];
264 273
265 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); 274 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
266 if (password) 275 if (password)
267 strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE); 276 strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
268 277
269 if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) { 278 if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
270 memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE); 279 memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
271 memcpy(lnm_session_key, password_with_pad, 280 memcpy(lnm_session_key, password_with_pad,
272 CIFS_ENCPWD_SIZE); 281 CIFS_ENCPWD_SIZE);
273 return; 282 return;
274 } 283 }
275 284
276 /* calculate old style session key */ 285 /* calculate old style session key */
277 /* calling toupper is less broken than repeatedly 286 /* calling toupper is less broken than repeatedly
278 calling nls_toupper would be since that will never 287 calling nls_toupper would be since that will never
279 work for UTF8, but neither handles multibyte code pages 288 work for UTF8, but neither handles multibyte code pages
280 but the only alternative would be converting to UCS-16 (Unicode) 289 but the only alternative would be converting to UCS-16 (Unicode)
281 (using a routine something like UniStrupr) then 290 (using a routine something like UniStrupr) then
282 uppercasing and then converting back from Unicode - which 291 uppercasing and then converting back from Unicode - which
283 would only worth doing it if we knew it were utf8. Basically 292 would only worth doing it if we knew it were utf8. Basically
284 utf8 and other multibyte codepages each need their own strupper 293 utf8 and other multibyte codepages each need their own strupper
285 function since a byte at a time will ont work. */ 294 function since a byte at a time will ont work. */
286 295
287 for (i = 0; i < CIFS_ENCPWD_SIZE; i++) 296 for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
288 password_with_pad[i] = toupper(password_with_pad[i]); 297 password_with_pad[i] = toupper(password_with_pad[i]);
289 298
290 SMBencrypt(password_with_pad, cryptkey, lnm_session_key); 299 SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
291 300
292 /* clear password before we return/free memory */ 301 /* clear password before we return/free memory */
293 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); 302 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
294 } 303 }
295 #endif /* CIFS_WEAK_PW_HASH */ 304 #endif /* CIFS_WEAK_PW_HASH */
296 305
297 /* Build a proper attribute value/target info pairs blob. 306 /* Build a proper attribute value/target info pairs blob.
298 * Fill in netbios and dns domain name and workstation name 307 * Fill in netbios and dns domain name and workstation name
299 * and client time (total five av pairs and + one end of fields indicator. 308 * and client time (total five av pairs and + one end of fields indicator.
300 * Allocate domain name which gets freed when session struct is deallocated. 309 * Allocate domain name which gets freed when session struct is deallocated.
301 */ 310 */
302 static int 311 static int
303 build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp) 312 build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
304 { 313 {
305 unsigned int dlen; 314 unsigned int dlen;
306 unsigned int wlen; 315 unsigned int wlen;
307 unsigned int size = 6 * sizeof(struct ntlmssp2_name); 316 unsigned int size = 6 * sizeof(struct ntlmssp2_name);
308 __le64 curtime; 317 __le64 curtime;
309 char *defdmname = "WORKGROUP"; 318 char *defdmname = "WORKGROUP";
310 unsigned char *blobptr; 319 unsigned char *blobptr;
311 struct ntlmssp2_name *attrptr; 320 struct ntlmssp2_name *attrptr;
312 321
313 if (!ses->domainName) { 322 if (!ses->domainName) {
314 ses->domainName = kstrdup(defdmname, GFP_KERNEL); 323 ses->domainName = kstrdup(defdmname, GFP_KERNEL);
315 if (!ses->domainName) 324 if (!ses->domainName)
316 return -ENOMEM; 325 return -ENOMEM;
317 } 326 }
318 327
319 dlen = strlen(ses->domainName); 328 dlen = strlen(ses->domainName);
320 wlen = strlen(ses->server->hostname); 329 wlen = strlen(ses->server->hostname);
321 330
322 /* The length of this blob is a size which is 331 /* The length of this blob is a size which is
323 * six times the size of a structure which holds name/size + 332 * six times the size of a structure which holds name/size +
324 * two times the unicode length of a domain name + 333 * two times the unicode length of a domain name +
325 * two times the unicode length of a server name + 334 * two times the unicode length of a server name +
326 * size of a timestamp (which is 8 bytes). 335 * size of a timestamp (which is 8 bytes).
327 */ 336 */
328 ses->auth_key.len = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8; 337 ses->auth_key.len = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
329 ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL); 338 ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
330 if (!ses->auth_key.response) { 339 if (!ses->auth_key.response) {
331 ses->auth_key.len = 0; 340 ses->auth_key.len = 0;
332 cERROR(1, "Challenge target info allocation failure"); 341 cERROR(1, "Challenge target info allocation failure");
333 return -ENOMEM; 342 return -ENOMEM;
334 } 343 }
335 344
336 blobptr = ses->auth_key.response; 345 blobptr = ses->auth_key.response;
337 attrptr = (struct ntlmssp2_name *) blobptr; 346 attrptr = (struct ntlmssp2_name *) blobptr;
338 347
339 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME); 348 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
340 attrptr->length = cpu_to_le16(2 * dlen); 349 attrptr->length = cpu_to_le16(2 * dlen);
341 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); 350 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
342 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp); 351 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
343 352
344 blobptr += 2 * dlen; 353 blobptr += 2 * dlen;
345 attrptr = (struct ntlmssp2_name *) blobptr; 354 attrptr = (struct ntlmssp2_name *) blobptr;
346 355
347 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME); 356 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME);
348 attrptr->length = cpu_to_le16(2 * wlen); 357 attrptr->length = cpu_to_le16(2 * wlen);
349 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); 358 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
350 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp); 359 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
351 360
352 blobptr += 2 * wlen; 361 blobptr += 2 * wlen;
353 attrptr = (struct ntlmssp2_name *) blobptr; 362 attrptr = (struct ntlmssp2_name *) blobptr;
354 363
355 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME); 364 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME);
356 attrptr->length = cpu_to_le16(2 * dlen); 365 attrptr->length = cpu_to_le16(2 * dlen);
357 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); 366 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
358 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp); 367 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
359 368
360 blobptr += 2 * dlen; 369 blobptr += 2 * dlen;
361 attrptr = (struct ntlmssp2_name *) blobptr; 370 attrptr = (struct ntlmssp2_name *) blobptr;
362 371
363 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME); 372 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME);
364 attrptr->length = cpu_to_le16(2 * wlen); 373 attrptr->length = cpu_to_le16(2 * wlen);
365 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); 374 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
366 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp); 375 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
367 376
368 blobptr += 2 * wlen; 377 blobptr += 2 * wlen;
369 attrptr = (struct ntlmssp2_name *) blobptr; 378 attrptr = (struct ntlmssp2_name *) blobptr;
370 379
371 attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP); 380 attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP);
372 attrptr->length = cpu_to_le16(sizeof(__le64)); 381 attrptr->length = cpu_to_le16(sizeof(__le64));
373 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); 382 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
374 curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 383 curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
375 memcpy(blobptr, &curtime, sizeof(__le64)); 384 memcpy(blobptr, &curtime, sizeof(__le64));
376 385
377 return 0; 386 return 0;
378 } 387 }
379 388
380 /* Server has provided av pairs/target info in the type 2 challenge 389 /* Server has provided av pairs/target info in the type 2 challenge
381 * packet and we have plucked it and stored within smb session. 390 * packet and we have plucked it and stored within smb session.
382 * We parse that blob here to find netbios domain name to be used 391 * We parse that blob here to find netbios domain name to be used
383 * as part of ntlmv2 authentication (in Target String), if not already 392 * as part of ntlmv2 authentication (in Target String), if not already
384 * specified on the command line. 393 * specified on the command line.
385 * If this function returns without any error but without fetching 394 * If this function returns without any error but without fetching
386 * domain name, authentication may fail against some server but 395 * domain name, authentication may fail against some server but
387 * may not fail against other (those who are not very particular 396 * may not fail against other (those who are not very particular
388 * about target string i.e. for some, just user name might suffice. 397 * about target string i.e. for some, just user name might suffice.
389 */ 398 */
390 static int 399 static int
391 find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) 400 find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
392 { 401 {
393 unsigned int attrsize; 402 unsigned int attrsize;
394 unsigned int type; 403 unsigned int type;
395 unsigned int onesize = sizeof(struct ntlmssp2_name); 404 unsigned int onesize = sizeof(struct ntlmssp2_name);
396 unsigned char *blobptr; 405 unsigned char *blobptr;
397 unsigned char *blobend; 406 unsigned char *blobend;
398 struct ntlmssp2_name *attrptr; 407 struct ntlmssp2_name *attrptr;
399 408
400 if (!ses->auth_key.len || !ses->auth_key.response) 409 if (!ses->auth_key.len || !ses->auth_key.response)
401 return 0; 410 return 0;
402 411
403 blobptr = ses->auth_key.response; 412 blobptr = ses->auth_key.response;
404 blobend = blobptr + ses->auth_key.len; 413 blobend = blobptr + ses->auth_key.len;
405 414
406 while (blobptr + onesize < blobend) { 415 while (blobptr + onesize < blobend) {
407 attrptr = (struct ntlmssp2_name *) blobptr; 416 attrptr = (struct ntlmssp2_name *) blobptr;
408 type = le16_to_cpu(attrptr->type); 417 type = le16_to_cpu(attrptr->type);
409 if (type == NTLMSSP_AV_EOL) 418 if (type == NTLMSSP_AV_EOL)
410 break; 419 break;
411 blobptr += 2; /* advance attr type */ 420 blobptr += 2; /* advance attr type */
412 attrsize = le16_to_cpu(attrptr->length); 421 attrsize = le16_to_cpu(attrptr->length);
413 blobptr += 2; /* advance attr size */ 422 blobptr += 2; /* advance attr size */
414 if (blobptr + attrsize > blobend) 423 if (blobptr + attrsize > blobend)
415 break; 424 break;
416 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) { 425 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
417 if (!attrsize) 426 if (!attrsize)
418 break; 427 break;
419 if (!ses->domainName) { 428 if (!ses->domainName) {
420 ses->domainName = 429 ses->domainName =
421 kmalloc(attrsize + 1, GFP_KERNEL); 430 kmalloc(attrsize + 1, GFP_KERNEL);
422 if (!ses->domainName) 431 if (!ses->domainName)
423 return -ENOMEM; 432 return -ENOMEM;
424 cifs_from_ucs2(ses->domainName, 433 cifs_from_ucs2(ses->domainName,
425 (__le16 *)blobptr, attrsize, attrsize, 434 (__le16 *)blobptr, attrsize, attrsize,
426 nls_cp, false); 435 nls_cp, false);
427 break; 436 break;
428 } 437 }
429 } 438 }
430 blobptr += attrsize; /* advance attr value */ 439 blobptr += attrsize; /* advance attr value */
431 } 440 }
432 441
433 return 0; 442 return 0;
434 } 443 }
435 444
436 static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash, 445 static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
437 const struct nls_table *nls_cp) 446 const struct nls_table *nls_cp)
438 { 447 {
439 int rc = 0; 448 int rc = 0;
440 int len; 449 int len;
441 char nt_hash[CIFS_NTHASH_SIZE]; 450 char nt_hash[CIFS_NTHASH_SIZE];
442 wchar_t *user; 451 wchar_t *user;
443 wchar_t *domain; 452 wchar_t *domain;
444 wchar_t *server; 453 wchar_t *server;
445 454
446 if (!ses->server->secmech.sdeschmacmd5) { 455 if (!ses->server->secmech.sdeschmacmd5) {
447 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); 456 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
448 return -1; 457 return -1;
449 } 458 }
450 459
451 /* calculate md4 hash of password */ 460 /* calculate md4 hash of password */
452 E_md4hash(ses->password, nt_hash); 461 E_md4hash(ses->password, nt_hash);
453 462
454 crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, 463 crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
455 CIFS_NTHASH_SIZE); 464 CIFS_NTHASH_SIZE);
456 465
457 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); 466 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
458 if (rc) { 467 if (rc) {
459 cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); 468 cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
460 return rc; 469 return rc;
461 } 470 }
462 471
463 /* convert ses->userName to unicode and uppercase */ 472 /* convert ses->userName to unicode and uppercase */
464 len = strlen(ses->userName); 473 len = strlen(ses->userName);
465 user = kmalloc(2 + (len * 2), GFP_KERNEL); 474 user = kmalloc(2 + (len * 2), GFP_KERNEL);
466 if (user == NULL) { 475 if (user == NULL) {
467 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); 476 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
468 rc = -ENOMEM; 477 rc = -ENOMEM;
469 goto calc_exit_2; 478 goto calc_exit_2;
470 } 479 }
471 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 480 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
472 UniStrupr(user); 481 UniStrupr(user);
473 482
474 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 483 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
475 (char *)user, 2 * len); 484 (char *)user, 2 * len);
476 485
477 /* convert ses->domainName to unicode and uppercase */ 486 /* convert ses->domainName to unicode and uppercase */
478 if (ses->domainName) { 487 if (ses->domainName) {
479 len = strlen(ses->domainName); 488 len = strlen(ses->domainName);
480 489
481 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 490 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
482 if (domain == NULL) { 491 if (domain == NULL) {
483 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); 492 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
484 rc = -ENOMEM; 493 rc = -ENOMEM;
485 goto calc_exit_1; 494 goto calc_exit_1;
486 } 495 }
487 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, 496 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
488 nls_cp); 497 nls_cp);
489 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 498 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
490 (char *)domain, 2 * len); 499 (char *)domain, 2 * len);
491 kfree(domain); 500 kfree(domain);
492 } else if (ses->serverName) { 501 } else if (ses->serverName) {
493 len = strlen(ses->serverName); 502 len = strlen(ses->serverName);
494 503
495 server = kmalloc(2 + (len * 2), GFP_KERNEL); 504 server = kmalloc(2 + (len * 2), GFP_KERNEL);
496 if (server == NULL) { 505 if (server == NULL) {
497 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); 506 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
498 rc = -ENOMEM; 507 rc = -ENOMEM;
499 goto calc_exit_1; 508 goto calc_exit_1;
500 } 509 }
501 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, 510 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
502 nls_cp); 511 nls_cp);
503 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 512 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
504 (char *)server, 2 * len); 513 (char *)server, 2 * len);
505 kfree(server); 514 kfree(server);
506 } 515 }
507 516
508 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, 517 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
509 ntlmv2_hash); 518 ntlmv2_hash);
510 519
511 calc_exit_1: 520 calc_exit_1:
512 kfree(user); 521 kfree(user);
513 calc_exit_2: 522 calc_exit_2:
514 return rc; 523 return rc;
515 } 524 }
516 525
517 static int 526 static int
518 CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash) 527 CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
519 { 528 {
520 int rc; 529 int rc;
521 unsigned int offset = CIFS_SESS_KEY_SIZE + 8; 530 unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
522 531
523 if (!ses->server->secmech.sdeschmacmd5) { 532 if (!ses->server->secmech.sdeschmacmd5) {
524 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); 533 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
525 return -1; 534 return -1;
526 } 535 }
527 536
528 crypto_shash_setkey(ses->server->secmech.hmacmd5, 537 crypto_shash_setkey(ses->server->secmech.hmacmd5,
529 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 538 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
530 539
531 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); 540 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
532 if (rc) { 541 if (rc) {
533 cERROR(1, "CalcNTLMv2_response: could not init hmacmd5"); 542 cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
534 return rc; 543 return rc;
535 } 544 }
536 545
537 if (ses->server->secType == RawNTLMSSP) 546 if (ses->server->secType == RawNTLMSSP)
538 memcpy(ses->auth_key.response + offset, 547 memcpy(ses->auth_key.response + offset,
539 ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 548 ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
540 else 549 else
541 memcpy(ses->auth_key.response + offset, 550 memcpy(ses->auth_key.response + offset,
542 ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 551 ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
543 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 552 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
544 ses->auth_key.response + offset, ses->auth_key.len - offset); 553 ses->auth_key.response + offset, ses->auth_key.len - offset);
545 554
546 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, 555 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
547 ses->auth_key.response + CIFS_SESS_KEY_SIZE); 556 ses->auth_key.response + CIFS_SESS_KEY_SIZE);
548 557
549 return rc; 558 return rc;
550 } 559 }
551 560
552 561
553 int 562 int
554 setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) 563 setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
555 { 564 {
556 int rc; 565 int rc;
557 int baselen; 566 int baselen;
558 unsigned int tilen; 567 unsigned int tilen;
559 struct ntlmv2_resp *buf; 568 struct ntlmv2_resp *buf;
560 char ntlmv2_hash[16]; 569 char ntlmv2_hash[16];
561 unsigned char *tiblob = NULL; /* target info blob */ 570 unsigned char *tiblob = NULL; /* target info blob */
562 571
563 if (ses->server->secType == RawNTLMSSP) { 572 if (ses->server->secType == RawNTLMSSP) {
564 if (!ses->domainName) { 573 if (!ses->domainName) {
565 rc = find_domain_name(ses, nls_cp); 574 rc = find_domain_name(ses, nls_cp);
566 if (rc) { 575 if (rc) {
567 cERROR(1, "error %d finding domain name", rc); 576 cERROR(1, "error %d finding domain name", rc);
568 goto setup_ntlmv2_rsp_ret; 577 goto setup_ntlmv2_rsp_ret;
569 } 578 }
570 } 579 }
571 } else { 580 } else {
572 rc = build_avpair_blob(ses, nls_cp); 581 rc = build_avpair_blob(ses, nls_cp);
573 if (rc) { 582 if (rc) {
574 cERROR(1, "error %d building av pair blob", rc); 583 cERROR(1, "error %d building av pair blob", rc);
575 goto setup_ntlmv2_rsp_ret; 584 goto setup_ntlmv2_rsp_ret;
576 } 585 }
577 } 586 }
578 587
579 baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); 588 baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
580 tilen = ses->auth_key.len; 589 tilen = ses->auth_key.len;
581 tiblob = ses->auth_key.response; 590 tiblob = ses->auth_key.response;
582 591
583 ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL); 592 ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
584 if (!ses->auth_key.response) { 593 if (!ses->auth_key.response) {
585 rc = ENOMEM; 594 rc = ENOMEM;
586 ses->auth_key.len = 0; 595 ses->auth_key.len = 0;
587 cERROR(1, "%s: Can't allocate auth blob", __func__); 596 cERROR(1, "%s: Can't allocate auth blob", __func__);
588 goto setup_ntlmv2_rsp_ret; 597 goto setup_ntlmv2_rsp_ret;
589 } 598 }
590 ses->auth_key.len += baselen; 599 ses->auth_key.len += baselen;
591 600
592 buf = (struct ntlmv2_resp *) 601 buf = (struct ntlmv2_resp *)
593 (ses->auth_key.response + CIFS_SESS_KEY_SIZE); 602 (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
594 buf->blob_signature = cpu_to_le32(0x00000101); 603 buf->blob_signature = cpu_to_le32(0x00000101);
595 buf->reserved = 0; 604 buf->reserved = 0;
596 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 605 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
597 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 606 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
598 buf->reserved2 = 0; 607 buf->reserved2 = 0;
599 608
600 memcpy(ses->auth_key.response + baselen, tiblob, tilen); 609 memcpy(ses->auth_key.response + baselen, tiblob, tilen);
601 610
602 /* calculate ntlmv2_hash */ 611 /* calculate ntlmv2_hash */
603 rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); 612 rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
604 if (rc) { 613 if (rc) {
605 cERROR(1, "could not get v2 hash rc %d", rc); 614 cERROR(1, "could not get v2 hash rc %d", rc);
606 goto setup_ntlmv2_rsp_ret; 615 goto setup_ntlmv2_rsp_ret;
607 } 616 }
608 617
609 /* calculate first part of the client response (CR1) */ 618 /* calculate first part of the client response (CR1) */
610 rc = CalcNTLMv2_response(ses, ntlmv2_hash); 619 rc = CalcNTLMv2_response(ses, ntlmv2_hash);
611 if (rc) { 620 if (rc) {
612 cERROR(1, "Could not calculate CR1 rc: %d", rc); 621 cERROR(1, "Could not calculate CR1 rc: %d", rc);
613 goto setup_ntlmv2_rsp_ret; 622 goto setup_ntlmv2_rsp_ret;
614 } 623 }
615 624
616 /* now calculate the session key for NTLMv2 */ 625 /* now calculate the session key for NTLMv2 */
617 crypto_shash_setkey(ses->server->secmech.hmacmd5, 626 crypto_shash_setkey(ses->server->secmech.hmacmd5,
618 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 627 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
619 628
620 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); 629 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
621 if (rc) { 630 if (rc) {
622 cERROR(1, "%s: Could not init hmacmd5\n", __func__); 631 cERROR(1, "%s: Could not init hmacmd5\n", __func__);
623 goto setup_ntlmv2_rsp_ret; 632 goto setup_ntlmv2_rsp_ret;
624 } 633 }
625 634
626 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 635 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
627 ses->auth_key.response + CIFS_SESS_KEY_SIZE, 636 ses->auth_key.response + CIFS_SESS_KEY_SIZE,
628 CIFS_HMAC_MD5_HASH_SIZE); 637 CIFS_HMAC_MD5_HASH_SIZE);
629 638
630 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, 639 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
631 ses->auth_key.response); 640 ses->auth_key.response);
632 641
633 setup_ntlmv2_rsp_ret: 642 setup_ntlmv2_rsp_ret:
634 kfree(tiblob); 643 kfree(tiblob);
635 644
636 return rc; 645 return rc;
637 } 646 }
638 647
639 int 648 int
640 calc_seckey(struct cifsSesInfo *ses) 649 calc_seckey(struct cifsSesInfo *ses)
641 { 650 {
642 int rc; 651 int rc;
643 struct crypto_blkcipher *tfm_arc4; 652 struct crypto_blkcipher *tfm_arc4;
644 struct scatterlist sgin, sgout; 653 struct scatterlist sgin, sgout;
645 struct blkcipher_desc desc; 654 struct blkcipher_desc desc;
646 unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */ 655 unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
647 656
648 get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); 657 get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
649 658
650 tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 659 tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
651 if (!tfm_arc4 || IS_ERR(tfm_arc4)) { 660 if (!tfm_arc4 || IS_ERR(tfm_arc4)) {
652 cERROR(1, "could not allocate crypto API arc4\n"); 661 cERROR(1, "could not allocate crypto API arc4\n");
653 return PTR_ERR(tfm_arc4); 662 return PTR_ERR(tfm_arc4);
654 } 663 }
655 664
656 desc.tfm = tfm_arc4; 665 desc.tfm = tfm_arc4;
657 666
658 crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response, 667 crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response,
659 CIFS_SESS_KEY_SIZE); 668 CIFS_SESS_KEY_SIZE);
660 669
661 sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE); 670 sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
662 sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); 671 sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
663 672
664 rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE); 673 rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
665 if (rc) { 674 if (rc) {
666 cERROR(1, "could not encrypt session key rc: %d\n", rc); 675 cERROR(1, "could not encrypt session key rc: %d\n", rc);
667 crypto_free_blkcipher(tfm_arc4); 676 crypto_free_blkcipher(tfm_arc4);
668 return rc; 677 return rc;
669 } 678 }
670 679
671 /* make secondary_key/nonce as session key */ 680 /* make secondary_key/nonce as session key */
672 memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE); 681 memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
673 /* and make len as that of session key only */ 682 /* and make len as that of session key only */
674 ses->auth_key.len = CIFS_SESS_KEY_SIZE; 683 ses->auth_key.len = CIFS_SESS_KEY_SIZE;
675 684
676 crypto_free_blkcipher(tfm_arc4); 685 crypto_free_blkcipher(tfm_arc4);
677 686
678 return 0; 687 return 0;
679 } 688 }
680 689
681 void 690 void
682 cifs_crypto_shash_release(struct TCP_Server_Info *server) 691 cifs_crypto_shash_release(struct TCP_Server_Info *server)
683 { 692 {
684 if (server->secmech.md5) 693 if (server->secmech.md5)
685 crypto_free_shash(server->secmech.md5); 694 crypto_free_shash(server->secmech.md5);
686 695
687 if (server->secmech.hmacmd5) 696 if (server->secmech.hmacmd5)
688 crypto_free_shash(server->secmech.hmacmd5); 697 crypto_free_shash(server->secmech.hmacmd5);
689 698
690 kfree(server->secmech.sdeschmacmd5); 699 kfree(server->secmech.sdeschmacmd5);
691 700
692 kfree(server->secmech.sdescmd5); 701 kfree(server->secmech.sdescmd5);
693 } 702 }
694 703
695 int 704 int
696 cifs_crypto_shash_allocate(struct TCP_Server_Info *server) 705 cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
697 { 706 {
698 int rc; 707 int rc;
699 unsigned int size; 708 unsigned int size;
700 709
701 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 710 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
702 if (!server->secmech.hmacmd5 || 711 if (IS_ERR(server->secmech.hmacmd5)) {
703 IS_ERR(server->secmech.hmacmd5)) {
704 cERROR(1, "could not allocate crypto hmacmd5\n"); 712 cERROR(1, "could not allocate crypto hmacmd5\n");
705 return PTR_ERR(server->secmech.hmacmd5); 713 return PTR_ERR(server->secmech.hmacmd5);
706 } 714 }
707 715
708 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); 716 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
709 if (!server->secmech.md5 || IS_ERR(server->secmech.md5)) { 717 if (IS_ERR(server->secmech.md5)) {
710 cERROR(1, "could not allocate crypto md5\n"); 718 cERROR(1, "could not allocate crypto md5\n");
711 rc = PTR_ERR(server->secmech.md5); 719 rc = PTR_ERR(server->secmech.md5);
712 goto crypto_allocate_md5_fail; 720 goto crypto_allocate_md5_fail;
713 } 721 }
714 722
715 size = sizeof(struct shash_desc) + 723 size = sizeof(struct shash_desc) +
716 crypto_shash_descsize(server->secmech.hmacmd5); 724 crypto_shash_descsize(server->secmech.hmacmd5);
717 server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); 725 server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
718 if (!server->secmech.sdeschmacmd5) { 726 if (!server->secmech.sdeschmacmd5) {
719 cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n"); 727 cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
720 rc = -ENOMEM; 728 rc = -ENOMEM;
721 goto crypto_allocate_hmacmd5_sdesc_fail; 729 goto crypto_allocate_hmacmd5_sdesc_fail;
722 } 730 }
723 server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5; 731 server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
724 server->secmech.sdeschmacmd5->shash.flags = 0x0; 732 server->secmech.sdeschmacmd5->shash.flags = 0x0;
725 733
726 734
727 size = sizeof(struct shash_desc) + 735 size = sizeof(struct shash_desc) +
728 crypto_shash_descsize(server->secmech.md5); 736 crypto_shash_descsize(server->secmech.md5);
729 server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL); 737 server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
730 if (!server->secmech.sdescmd5) { 738 if (!server->secmech.sdescmd5) {
731 cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n"); 739 cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
732 rc = -ENOMEM; 740 rc = -ENOMEM;
733 goto crypto_allocate_md5_sdesc_fail; 741 goto crypto_allocate_md5_sdesc_fail;
734 } 742 }
735 server->secmech.sdescmd5->shash.tfm = server->secmech.md5; 743 server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
736 server->secmech.sdescmd5->shash.flags = 0x0; 744 server->secmech.sdescmd5->shash.flags = 0x0;
737 745
738 return 0; 746 return 0;
739 747
740 crypto_allocate_md5_sdesc_fail: 748 crypto_allocate_md5_sdesc_fail:
741 kfree(server->secmech.sdeschmacmd5); 749 kfree(server->secmech.sdeschmacmd5);
742 750
743 crypto_allocate_hmacmd5_sdesc_fail: 751 crypto_allocate_hmacmd5_sdesc_fail:
744 crypto_free_shash(server->secmech.md5); 752 crypto_free_shash(server->secmech.md5);
745 753
fs/cifs/cifsencrypt.h
1 /* File was deleted
2 * fs/cifs/cifsencrypt.h
3 *
4 * Copyright (c) International Business Machines Corp., 2005
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * Externs for misc. small encryption routines
8 * so we do not have to put them in cifsproto.h
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 /* md4.c */
26 extern void mdfour(unsigned char *out, unsigned char *in, int n);
27 /* smbdes.c */
28 extern void E_P16(unsigned char *p14, unsigned char *p16);
29 extern void E_P24(unsigned char *p21, const unsigned char *c8,
30 unsigned char *p24);
31 1 /*
32 2 * fs/cifs/cifsencrypt.h
33 3 *
34 4 * Copyright (c) International Business Machines Corp., 2005
1 /* 1 /*
2 * fs/cifs/cifsproto.h 2 * fs/cifs/cifsproto.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002,2008 4 * Copyright (c) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published 8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or 9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details. 15 * the GNU Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 #ifndef _CIFSPROTO_H 21 #ifndef _CIFSPROTO_H
22 #define _CIFSPROTO_H 22 #define _CIFSPROTO_H
23 #include <linux/nls.h> 23 #include <linux/nls.h>
24 24
25 struct statfs; 25 struct statfs;
26 struct smb_vol; 26 struct smb_vol;
27 27
28 /* 28 /*
29 ***************************************************************** 29 *****************************************************************
30 * All Prototypes 30 * All Prototypes
31 ***************************************************************** 31 *****************************************************************
32 */ 32 */
33 33
34 extern struct smb_hdr *cifs_buf_get(void); 34 extern struct smb_hdr *cifs_buf_get(void);
35 extern void cifs_buf_release(void *); 35 extern void cifs_buf_release(void *);
36 extern struct smb_hdr *cifs_small_buf_get(void); 36 extern struct smb_hdr *cifs_small_buf_get(void);
37 extern void cifs_small_buf_release(void *); 37 extern void cifs_small_buf_release(void *);
38 extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *, 38 extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
39 unsigned int /* length */); 39 unsigned int /* length */);
40 extern unsigned int _GetXid(void); 40 extern unsigned int _GetXid(void);
41 extern void _FreeXid(unsigned int); 41 extern void _FreeXid(unsigned int);
42 #define GetXid() \ 42 #define GetXid() \
43 ({ \ 43 ({ \
44 int __xid = (int)_GetXid(); \ 44 int __xid = (int)_GetXid(); \
45 cFYI(1, "CIFS VFS: in %s as Xid: %d with uid: %d", \ 45 cFYI(1, "CIFS VFS: in %s as Xid: %d with uid: %d", \
46 __func__, __xid, current_fsuid()); \ 46 __func__, __xid, current_fsuid()); \
47 __xid; \ 47 __xid; \
48 }) 48 })
49 49
50 #define FreeXid(curr_xid) \ 50 #define FreeXid(curr_xid) \
51 do { \ 51 do { \
52 _FreeXid(curr_xid); \ 52 _FreeXid(curr_xid); \
53 cFYI(1, "CIFS VFS: leaving %s (xid = %d) rc = %d", \ 53 cFYI(1, "CIFS VFS: leaving %s (xid = %d) rc = %d", \
54 __func__, curr_xid, (int)rc); \ 54 __func__, curr_xid, (int)rc); \
55 } while (0) 55 } while (0)
56 extern char *build_path_from_dentry(struct dentry *); 56 extern char *build_path_from_dentry(struct dentry *);
57 extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, 57 extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
58 struct cifsTconInfo *tcon); 58 struct cifsTconInfo *tcon);
59 extern char *build_wildcard_path_from_dentry(struct dentry *direntry); 59 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
60 extern char *cifs_compose_mount_options(const char *sb_mountdata, 60 extern char *cifs_compose_mount_options(const char *sb_mountdata,
61 const char *fullpath, const struct dfs_info3_param *ref, 61 const char *fullpath, const struct dfs_info3_param *ref,
62 char **devname); 62 char **devname);
63 /* extern void renew_parental_timestamps(struct dentry *direntry);*/ 63 /* extern void renew_parental_timestamps(struct dentry *direntry);*/
64 extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer, 64 extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
65 struct TCP_Server_Info *server); 65 struct TCP_Server_Info *server);
66 extern void DeleteMidQEntry(struct mid_q_entry *midEntry); 66 extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
67 extern int cifs_call_async(struct TCP_Server_Info *server, 67 extern int cifs_call_async(struct TCP_Server_Info *server,
68 struct smb_hdr *in_buf, mid_callback_t *callback, 68 struct smb_hdr *in_buf, mid_callback_t *callback,
69 void *cbdata); 69 void *cbdata);
70 extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, 70 extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
71 struct smb_hdr * /* input */ , 71 struct smb_hdr * /* input */ ,
72 struct smb_hdr * /* out */ , 72 struct smb_hdr * /* out */ ,
73 int * /* bytes returned */ , const int long_op); 73 int * /* bytes returned */ , const int long_op);
74 extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, 74 extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
75 struct smb_hdr *in_buf, int flags); 75 struct smb_hdr *in_buf, int flags);
76 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 76 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
77 struct kvec *, int /* nvec to send */, 77 struct kvec *, int /* nvec to send */,
78 int * /* type of buf returned */ , const int flags); 78 int * /* type of buf returned */ , const int flags);
79 extern int SendReceiveBlockingLock(const unsigned int xid, 79 extern int SendReceiveBlockingLock(const unsigned int xid,
80 struct cifsTconInfo *ptcon, 80 struct cifsTconInfo *ptcon,
81 struct smb_hdr *in_buf , 81 struct smb_hdr *in_buf ,
82 struct smb_hdr *out_buf, 82 struct smb_hdr *out_buf,
83 int *bytes_returned); 83 int *bytes_returned);
84 extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); 84 extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
85 extern bool is_valid_oplock_break(struct smb_hdr *smb, 85 extern bool is_valid_oplock_break(struct smb_hdr *smb,
86 struct TCP_Server_Info *); 86 struct TCP_Server_Info *);
87 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); 87 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
88 extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, 88 extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
89 unsigned int bytes_written); 89 unsigned int bytes_written);
90 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); 90 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
91 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); 91 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
92 extern unsigned int smbCalcSize(struct smb_hdr *ptr); 92 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
93 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); 93 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
94 extern int decode_negTokenInit(unsigned char *security_blob, int length, 94 extern int decode_negTokenInit(unsigned char *security_blob, int length,
95 struct TCP_Server_Info *server); 95 struct TCP_Server_Info *server);
96 extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); 96 extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
97 extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); 97 extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port);
98 extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, 98 extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
99 const unsigned short int port); 99 const unsigned short int port);
100 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); 100 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
101 extern void header_assemble(struct smb_hdr *, char /* command */ , 101 extern void header_assemble(struct smb_hdr *, char /* command */ ,
102 const struct cifsTconInfo *, int /* length of 102 const struct cifsTconInfo *, int /* length of
103 fixed section (word count) in two byte units */); 103 fixed section (word count) in two byte units */);
104 extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 104 extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
105 struct cifsSesInfo *ses, 105 struct cifsSesInfo *ses,
106 void **request_buf); 106 void **request_buf);
107 extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 107 extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
108 const struct nls_table *nls_cp); 108 const struct nls_table *nls_cp);
109 extern __u16 GetNextMid(struct TCP_Server_Info *server); 109 extern __u16 GetNextMid(struct TCP_Server_Info *server);
110 extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 110 extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
111 extern u64 cifs_UnixTimeToNT(struct timespec); 111 extern u64 cifs_UnixTimeToNT(struct timespec);
112 extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 112 extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
113 int offset); 113 int offset);
114 extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); 114 extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
115 115
116 extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, 116 extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle,
117 struct file *file, struct tcon_link *tlink, 117 struct file *file, struct tcon_link *tlink,
118 __u32 oplock); 118 __u32 oplock);
119 extern int cifs_posix_open(char *full_path, struct inode **pinode, 119 extern int cifs_posix_open(char *full_path, struct inode **pinode,
120 struct super_block *sb, 120 struct super_block *sb,
121 int mode, unsigned int f_flags, 121 int mode, unsigned int f_flags,
122 __u32 *poplock, __u16 *pnetfid, int xid); 122 __u32 *poplock, __u16 *pnetfid, int xid);
123 void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr); 123 void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
124 extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, 124 extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
125 FILE_UNIX_BASIC_INFO *info, 125 FILE_UNIX_BASIC_INFO *info,
126 struct cifs_sb_info *cifs_sb); 126 struct cifs_sb_info *cifs_sb);
127 extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr); 127 extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
128 extern struct inode *cifs_iget(struct super_block *sb, 128 extern struct inode *cifs_iget(struct super_block *sb,
129 struct cifs_fattr *fattr); 129 struct cifs_fattr *fattr);
130 130
131 extern int cifs_get_file_info(struct file *filp); 131 extern int cifs_get_file_info(struct file *filp);
132 extern int cifs_get_inode_info(struct inode **pinode, 132 extern int cifs_get_inode_info(struct inode **pinode,
133 const unsigned char *search_path, 133 const unsigned char *search_path,
134 FILE_ALL_INFO *pfile_info, 134 FILE_ALL_INFO *pfile_info,
135 struct super_block *sb, int xid, const __u16 *pfid); 135 struct super_block *sb, int xid, const __u16 *pfid);
136 extern int cifs_get_file_info_unix(struct file *filp); 136 extern int cifs_get_file_info_unix(struct file *filp);
137 extern int cifs_get_inode_info_unix(struct inode **pinode, 137 extern int cifs_get_inode_info_unix(struct inode **pinode,
138 const unsigned char *search_path, 138 const unsigned char *search_path,
139 struct super_block *sb, int xid); 139 struct super_block *sb, int xid);
140 extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, 140 extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
141 struct cifs_fattr *fattr, struct inode *inode, 141 struct cifs_fattr *fattr, struct inode *inode,
142 const char *path, const __u16 *pfid); 142 const char *path, const __u16 *pfid);
143 extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64); 143 extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64);
144 extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, 144 extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
145 const char *, u32 *); 145 const char *, u32 *);
146 146
147 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, 147 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
148 const char *); 148 const char *);
149 extern int cifs_umount(struct super_block *, struct cifs_sb_info *); 149 extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
150 extern void cifs_dfs_release_automount_timer(void); 150 extern void cifs_dfs_release_automount_timer(void);
151 void cifs_proc_init(void); 151 void cifs_proc_init(void);
152 void cifs_proc_clean(void); 152 void cifs_proc_clean(void);
153 153
154 extern int cifs_negotiate_protocol(unsigned int xid, 154 extern int cifs_negotiate_protocol(unsigned int xid,
155 struct cifsSesInfo *ses); 155 struct cifsSesInfo *ses);
156 extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, 156 extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
157 struct nls_table *nls_info); 157 struct nls_table *nls_info);
158 extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); 158 extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
159 159
160 extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 160 extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
161 const char *tree, struct cifsTconInfo *tcon, 161 const char *tree, struct cifsTconInfo *tcon,
162 const struct nls_table *); 162 const struct nls_table *);
163 163
164 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 164 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
165 const char *searchName, const struct nls_table *nls_codepage, 165 const char *searchName, const struct nls_table *nls_codepage,
166 __u16 *searchHandle, struct cifs_search_info *psrch_inf, 166 __u16 *searchHandle, struct cifs_search_info *psrch_inf,
167 int map, const char dirsep); 167 int map, const char dirsep);
168 168
169 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 169 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
170 __u16 searchHandle, struct cifs_search_info *psrch_inf); 170 __u16 searchHandle, struct cifs_search_info *psrch_inf);
171 171
172 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, 172 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
173 const __u16 search_handle); 173 const __u16 search_handle);
174 174
175 extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, 175 extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
176 u16 netfid, FILE_ALL_INFO *pFindData); 176 u16 netfid, FILE_ALL_INFO *pFindData);
177 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 177 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
178 const unsigned char *searchName, 178 const unsigned char *searchName,
179 FILE_ALL_INFO *findData, 179 FILE_ALL_INFO *findData,
180 int legacy /* whether to use old info level */, 180 int legacy /* whether to use old info level */,
181 const struct nls_table *nls_codepage, int remap); 181 const struct nls_table *nls_codepage, int remap);
182 extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 182 extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
183 const unsigned char *searchName, 183 const unsigned char *searchName,
184 FILE_ALL_INFO *findData, 184 FILE_ALL_INFO *findData,
185 const struct nls_table *nls_codepage, int remap); 185 const struct nls_table *nls_codepage, int remap);
186 186
187 extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, 187 extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
188 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData); 188 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
189 extern int CIFSSMBUnixQPathInfo(const int xid, 189 extern int CIFSSMBUnixQPathInfo(const int xid,
190 struct cifsTconInfo *tcon, 190 struct cifsTconInfo *tcon,
191 const unsigned char *searchName, 191 const unsigned char *searchName,
192 FILE_UNIX_BASIC_INFO *pFindData, 192 FILE_UNIX_BASIC_INFO *pFindData,
193 const struct nls_table *nls_codepage, int remap); 193 const struct nls_table *nls_codepage, int remap);
194 194
195 extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 195 extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
196 const unsigned char *searchName, 196 const unsigned char *searchName,
197 struct dfs_info3_param **target_nodes, 197 struct dfs_info3_param **target_nodes,
198 unsigned int *number_of_nodes_in_array, 198 unsigned int *number_of_nodes_in_array,
199 const struct nls_table *nls_codepage, int remap); 199 const struct nls_table *nls_codepage, int remap);
200 200
201 extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 201 extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
202 const char *old_path, 202 const char *old_path,
203 const struct nls_table *nls_codepage, 203 const struct nls_table *nls_codepage,
204 unsigned int *pnum_referrals, 204 unsigned int *pnum_referrals,
205 struct dfs_info3_param **preferrals, 205 struct dfs_info3_param **preferrals,
206 int remap); 206 int remap);
207 extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 207 extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
208 struct super_block *sb, struct smb_vol *vol); 208 struct super_block *sb, struct smb_vol *vol);
209 extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, 209 extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
210 struct kstatfs *FSData); 210 struct kstatfs *FSData);
211 extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, 211 extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon,
212 struct kstatfs *FSData); 212 struct kstatfs *FSData);
213 extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, 213 extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
214 __u64 cap); 214 __u64 cap);
215 215
216 extern int CIFSSMBQFSAttributeInfo(const int xid, 216 extern int CIFSSMBQFSAttributeInfo(const int xid,
217 struct cifsTconInfo *tcon); 217 struct cifsTconInfo *tcon);
218 extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon); 218 extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
219 extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon); 219 extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon);
220 extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, 220 extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
221 struct kstatfs *FSData); 221 struct kstatfs *FSData);
222 222
223 extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, 223 extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
224 const char *fileName, const FILE_BASIC_INFO *data, 224 const char *fileName, const FILE_BASIC_INFO *data,
225 const struct nls_table *nls_codepage, 225 const struct nls_table *nls_codepage,
226 int remap_special_chars); 226 int remap_special_chars);
227 extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, 227 extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
228 const FILE_BASIC_INFO *data, __u16 fid, 228 const FILE_BASIC_INFO *data, __u16 fid,
229 __u32 pid_of_opener); 229 __u32 pid_of_opener);
230 extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, 230 extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
231 bool delete_file, __u16 fid, __u32 pid_of_opener); 231 bool delete_file, __u16 fid, __u32 pid_of_opener);
232 #if 0 232 #if 0
233 extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, 233 extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
234 char *fileName, __u16 dos_attributes, 234 char *fileName, __u16 dos_attributes,
235 const struct nls_table *nls_codepage); 235 const struct nls_table *nls_codepage);
236 #endif /* possibly unneeded function */ 236 #endif /* possibly unneeded function */
237 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, 237 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
238 const char *fileName, __u64 size, 238 const char *fileName, __u64 size,
239 bool setAllocationSizeFlag, 239 bool setAllocationSizeFlag,
240 const struct nls_table *nls_codepage, 240 const struct nls_table *nls_codepage,
241 int remap_special_chars); 241 int remap_special_chars);
242 extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, 242 extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
243 __u64 size, __u16 fileHandle, __u32 opener_pid, 243 __u64 size, __u16 fileHandle, __u32 opener_pid,
244 bool AllocSizeFlag); 244 bool AllocSizeFlag);
245 245
246 struct cifs_unix_set_info_args { 246 struct cifs_unix_set_info_args {
247 __u64 ctime; 247 __u64 ctime;
248 __u64 atime; 248 __u64 atime;
249 __u64 mtime; 249 __u64 mtime;
250 __u64 mode; 250 __u64 mode;
251 __u64 uid; 251 __u64 uid;
252 __u64 gid; 252 __u64 gid;
253 dev_t device; 253 dev_t device;
254 }; 254 };
255 255
256 extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, 256 extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
257 const struct cifs_unix_set_info_args *args, 257 const struct cifs_unix_set_info_args *args,
258 u16 fid, u32 pid_of_opener); 258 u16 fid, u32 pid_of_opener);
259 259
260 extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon, 260 extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon,
261 char *fileName, 261 char *fileName,
262 const struct cifs_unix_set_info_args *args, 262 const struct cifs_unix_set_info_args *args,
263 const struct nls_table *nls_codepage, 263 const struct nls_table *nls_codepage,
264 int remap_special_chars); 264 int remap_special_chars);
265 265
266 extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, 266 extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
267 const char *newName, 267 const char *newName,
268 const struct nls_table *nls_codepage, 268 const struct nls_table *nls_codepage,
269 int remap_special_chars); 269 int remap_special_chars);
270 extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, 270 extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
271 const char *name, const struct nls_table *nls_codepage, 271 const char *name, const struct nls_table *nls_codepage,
272 int remap_special_chars); 272 int remap_special_chars);
273 extern int CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, 273 extern int CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon,
274 const char *name, __u16 type, 274 const char *name, __u16 type,
275 const struct nls_table *nls_codepage, 275 const struct nls_table *nls_codepage,
276 int remap_special_chars); 276 int remap_special_chars);
277 extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, 277 extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
278 const char *name, 278 const char *name,
279 const struct nls_table *nls_codepage, 279 const struct nls_table *nls_codepage,
280 int remap_special_chars); 280 int remap_special_chars);
281 extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, 281 extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
282 const char *fromName, const char *toName, 282 const char *fromName, const char *toName,
283 const struct nls_table *nls_codepage, 283 const struct nls_table *nls_codepage,
284 int remap_special_chars); 284 int remap_special_chars);
285 extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, 285 extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
286 int netfid, const char *target_name, 286 int netfid, const char *target_name,
287 const struct nls_table *nls_codepage, 287 const struct nls_table *nls_codepage,
288 int remap_special_chars); 288 int remap_special_chars);
289 extern int CIFSCreateHardLink(const int xid, 289 extern int CIFSCreateHardLink(const int xid,
290 struct cifsTconInfo *tcon, 290 struct cifsTconInfo *tcon,
291 const char *fromName, const char *toName, 291 const char *fromName, const char *toName,
292 const struct nls_table *nls_codepage, 292 const struct nls_table *nls_codepage,
293 int remap_special_chars); 293 int remap_special_chars);
294 extern int CIFSUnixCreateHardLink(const int xid, 294 extern int CIFSUnixCreateHardLink(const int xid,
295 struct cifsTconInfo *tcon, 295 struct cifsTconInfo *tcon,
296 const char *fromName, const char *toName, 296 const char *fromName, const char *toName,
297 const struct nls_table *nls_codepage, 297 const struct nls_table *nls_codepage,
298 int remap_special_chars); 298 int remap_special_chars);
299 extern int CIFSUnixCreateSymLink(const int xid, 299 extern int CIFSUnixCreateSymLink(const int xid,
300 struct cifsTconInfo *tcon, 300 struct cifsTconInfo *tcon,
301 const char *fromName, const char *toName, 301 const char *fromName, const char *toName,
302 const struct nls_table *nls_codepage); 302 const struct nls_table *nls_codepage);
303 extern int CIFSSMBUnixQuerySymLink(const int xid, 303 extern int CIFSSMBUnixQuerySymLink(const int xid,
304 struct cifsTconInfo *tcon, 304 struct cifsTconInfo *tcon,
305 const unsigned char *searchName, char **syminfo, 305 const unsigned char *searchName, char **syminfo,
306 const struct nls_table *nls_codepage); 306 const struct nls_table *nls_codepage);
307 extern int CIFSSMBQueryReparseLinkInfo(const int xid, 307 extern int CIFSSMBQueryReparseLinkInfo(const int xid,
308 struct cifsTconInfo *tcon, 308 struct cifsTconInfo *tcon,
309 const unsigned char *searchName, 309 const unsigned char *searchName,
310 char *symlinkinfo, const int buflen, __u16 fid, 310 char *symlinkinfo, const int buflen, __u16 fid,
311 const struct nls_table *nls_codepage); 311 const struct nls_table *nls_codepage);
312 312
313 extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 313 extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
314 const char *fileName, const int disposition, 314 const char *fileName, const int disposition,
315 const int access_flags, const int omode, 315 const int access_flags, const int omode,
316 __u16 *netfid, int *pOplock, FILE_ALL_INFO *, 316 __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
317 const struct nls_table *nls_codepage, int remap); 317 const struct nls_table *nls_codepage, int remap);
318 extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 318 extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
319 const char *fileName, const int disposition, 319 const char *fileName, const int disposition,
320 const int access_flags, const int omode, 320 const int access_flags, const int omode,
321 __u16 *netfid, int *pOplock, FILE_ALL_INFO *, 321 __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
322 const struct nls_table *nls_codepage, int remap); 322 const struct nls_table *nls_codepage, int remap);
323 extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, 323 extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
324 u32 posix_flags, __u64 mode, __u16 *netfid, 324 u32 posix_flags, __u64 mode, __u16 *netfid,
325 FILE_UNIX_BASIC_INFO *pRetData, 325 FILE_UNIX_BASIC_INFO *pRetData,
326 __u32 *pOplock, const char *name, 326 __u32 *pOplock, const char *name,
327 const struct nls_table *nls_codepage, int remap); 327 const struct nls_table *nls_codepage, int remap);
328 extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, 328 extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
329 const int smb_file_id); 329 const int smb_file_id);
330 330
331 extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, 331 extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
332 const int smb_file_id); 332 const int smb_file_id);
333 333
334 extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 334 extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
335 const int netfid, unsigned int count, 335 const int netfid, unsigned int count,
336 const __u64 lseek, unsigned int *nbytes, char **buf, 336 const __u64 lseek, unsigned int *nbytes, char **buf,
337 int *return_buf_type); 337 int *return_buf_type);
338 extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 338 extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
339 const int netfid, const unsigned int count, 339 const int netfid, const unsigned int count,
340 const __u64 lseek, unsigned int *nbytes, 340 const __u64 lseek, unsigned int *nbytes,
341 const char *buf, const char __user *ubuf, 341 const char *buf, const char __user *ubuf,
342 const int long_op); 342 const int long_op);
343 extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 343 extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
344 const int netfid, const unsigned int count, 344 const int netfid, const unsigned int count,
345 const __u64 offset, unsigned int *nbytes, 345 const __u64 offset, unsigned int *nbytes,
346 struct kvec *iov, const int nvec, const int long_op); 346 struct kvec *iov, const int nvec, const int long_op);
347 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 347 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
348 const unsigned char *searchName, __u64 *inode_number, 348 const unsigned char *searchName, __u64 *inode_number,
349 const struct nls_table *nls_codepage, 349 const struct nls_table *nls_codepage,
350 int remap_special_chars); 350 int remap_special_chars);
351 extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen, 351 extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
352 const struct nls_table *cp, int mapChars); 352 const struct nls_table *cp, int mapChars);
353 353
354 extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, 354 extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
355 const __u16 netfid, const __u64 len, 355 const __u16 netfid, const __u64 len,
356 const __u64 offset, const __u32 numUnlock, 356 const __u64 offset, const __u32 numUnlock,
357 const __u32 numLock, const __u8 lockType, 357 const __u32 numLock, const __u8 lockType,
358 const bool waitFlag, const __u8 oplock_level); 358 const bool waitFlag, const __u8 oplock_level);
359 extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 359 extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
360 const __u16 smb_file_id, const int get_flag, 360 const __u16 smb_file_id, const int get_flag,
361 const __u64 len, struct file_lock *, 361 const __u64 len, struct file_lock *,
362 const __u16 lock_type, const bool waitFlag); 362 const __u16 lock_type, const bool waitFlag);
363 extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 363 extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
364 extern int CIFSSMBEcho(struct TCP_Server_Info *server); 364 extern int CIFSSMBEcho(struct TCP_Server_Info *server);
365 extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 365 extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
366 366
367 extern struct cifsSesInfo *sesInfoAlloc(void); 367 extern struct cifsSesInfo *sesInfoAlloc(void);
368 extern void sesInfoFree(struct cifsSesInfo *); 368 extern void sesInfoFree(struct cifsSesInfo *);
369 extern struct cifsTconInfo *tconInfoAlloc(void); 369 extern struct cifsTconInfo *tconInfoAlloc(void);
370 extern void tconInfoFree(struct cifsTconInfo *); 370 extern void tconInfoFree(struct cifsTconInfo *);
371 371
372 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *); 372 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
373 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 373 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
374 __u32 *); 374 __u32 *);
375 extern int cifs_verify_signature(struct smb_hdr *, 375 extern int cifs_verify_signature(struct smb_hdr *,
376 struct TCP_Server_Info *server, 376 struct TCP_Server_Info *server,
377 __u32 expected_sequence_number); 377 __u32 expected_sequence_number);
378 extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); 378 extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
379 extern int setup_ntlm_response(struct cifsSesInfo *); 379 extern int setup_ntlm_response(struct cifsSesInfo *);
380 extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *); 380 extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
381 extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); 381 extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
382 extern void cifs_crypto_shash_release(struct TCP_Server_Info *); 382 extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
383 extern int calc_seckey(struct cifsSesInfo *); 383 extern int calc_seckey(struct cifsSesInfo *);
384 384
385 #ifdef CONFIG_CIFS_WEAK_PW_HASH 385 #ifdef CONFIG_CIFS_WEAK_PW_HASH
386 extern void calc_lanman_hash(const char *password, const char *cryptkey, 386 extern void calc_lanman_hash(const char *password, const char *cryptkey,
387 bool encrypt, char *lnm_session_key); 387 bool encrypt, char *lnm_session_key);
388 #endif /* CIFS_WEAK_PW_HASH */ 388 #endif /* CIFS_WEAK_PW_HASH */
389 extern int CIFSSMBCopy(int xid, 389 extern int CIFSSMBCopy(int xid,
390 struct cifsTconInfo *source_tcon, 390 struct cifsTconInfo *source_tcon,
391 const char *fromName, 391 const char *fromName,
392 const __u16 target_tid, 392 const __u16 target_tid,
393 const char *toName, const int flags, 393 const char *toName, const int flags,
394 const struct nls_table *nls_codepage, 394 const struct nls_table *nls_codepage,
395 int remap_special_chars); 395 int remap_special_chars);
396 extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 396 extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
397 const int notify_subdirs, const __u16 netfid, 397 const int notify_subdirs, const __u16 netfid,
398 __u32 filter, struct file *file, int multishot, 398 __u32 filter, struct file *file, int multishot,
399 const struct nls_table *nls_codepage); 399 const struct nls_table *nls_codepage);
400 extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 400 extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
401 const unsigned char *searchName, 401 const unsigned char *searchName,
402 const unsigned char *ea_name, char *EAData, 402 const unsigned char *ea_name, char *EAData,
403 size_t bufsize, const struct nls_table *nls_codepage, 403 size_t bufsize, const struct nls_table *nls_codepage,
404 int remap_special_chars); 404 int remap_special_chars);
405 extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, 405 extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
406 const char *fileName, const char *ea_name, 406 const char *fileName, const char *ea_name,
407 const void *ea_value, const __u16 ea_value_len, 407 const void *ea_value, const __u16 ea_value_len,
408 const struct nls_table *nls_codepage, int remap_special_chars); 408 const struct nls_table *nls_codepage, int remap_special_chars);
409 extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, 409 extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
410 __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); 410 __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
411 extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16, 411 extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16,
412 struct cifs_ntsd *, __u32); 412 struct cifs_ntsd *, __u32);
413 extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 413 extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
414 const unsigned char *searchName, 414 const unsigned char *searchName,
415 char *acl_inf, const int buflen, const int acl_type, 415 char *acl_inf, const int buflen, const int acl_type,
416 const struct nls_table *nls_codepage, int remap_special_chars); 416 const struct nls_table *nls_codepage, int remap_special_chars);
417 extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 417 extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
418 const unsigned char *fileName, 418 const unsigned char *fileName,
419 const char *local_acl, const int buflen, const int acl_type, 419 const char *local_acl, const int buflen, const int acl_type,
420 const struct nls_table *nls_codepage, int remap_special_chars); 420 const struct nls_table *nls_codepage, int remap_special_chars);
421 extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 421 extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
422 const int netfid, __u64 *pExtAttrBits, __u64 *pMask); 422 const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
423 extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb); 423 extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
424 extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr); 424 extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
425 extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, 425 extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
426 const unsigned char *path, 426 const unsigned char *path,
427 struct cifs_sb_info *cifs_sb, int xid); 427 struct cifs_sb_info *cifs_sb, int xid);
428 extern int mdfour(unsigned char *, unsigned char *, int);
429 extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
430 extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
431 unsigned char *p24);
432 extern void E_P16(unsigned char *p14, unsigned char *p16);
433 extern void E_P24(unsigned char *p21, const unsigned char *c8,
434 unsigned char *p24);
428 #endif /* _CIFSPROTO_H */ 435 #endif /* _CIFSPROTO_H */
429 436
1 /* 1 /*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2009 4 * Copyright (C) International Business Machines Corp., 2002,2009
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published 8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or 9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details. 15 * the GNU Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 #include <linux/fs.h> 21 #include <linux/fs.h>
22 #include <linux/net.h> 22 #include <linux/net.h>
23 #include <linux/string.h> 23 #include <linux/string.h>
24 #include <linux/list.h> 24 #include <linux/list.h>
25 #include <linux/wait.h> 25 #include <linux/wait.h>
26 #include <linux/slab.h> 26 #include <linux/slab.h>
27 #include <linux/pagemap.h> 27 #include <linux/pagemap.h>
28 #include <linux/ctype.h> 28 #include <linux/ctype.h>
29 #include <linux/utsname.h> 29 #include <linux/utsname.h>
30 #include <linux/mempool.h> 30 #include <linux/mempool.h>
31 #include <linux/delay.h> 31 #include <linux/delay.h>
32 #include <linux/completion.h> 32 #include <linux/completion.h>
33 #include <linux/kthread.h> 33 #include <linux/kthread.h>
34 #include <linux/pagevec.h> 34 #include <linux/pagevec.h>
35 #include <linux/freezer.h> 35 #include <linux/freezer.h>
36 #include <linux/namei.h> 36 #include <linux/namei.h>
37 #include <asm/uaccess.h> 37 #include <asm/uaccess.h>
38 #include <asm/processor.h> 38 #include <asm/processor.h>
39 #include <linux/inet.h> 39 #include <linux/inet.h>
40 #include <net/ipv6.h> 40 #include <net/ipv6.h>
41 #include "cifspdu.h" 41 #include "cifspdu.h"
42 #include "cifsglob.h" 42 #include "cifsglob.h"
43 #include "cifsproto.h" 43 #include "cifsproto.h"
44 #include "cifs_unicode.h" 44 #include "cifs_unicode.h"
45 #include "cifs_debug.h" 45 #include "cifs_debug.h"
46 #include "cifs_fs_sb.h" 46 #include "cifs_fs_sb.h"
47 #include "ntlmssp.h" 47 #include "ntlmssp.h"
48 #include "nterr.h" 48 #include "nterr.h"
49 #include "rfc1002pdu.h" 49 #include "rfc1002pdu.h"
50 #include "fscache.h" 50 #include "fscache.h"
51 51
52 #define CIFS_PORT 445 52 #define CIFS_PORT 445
53 #define RFC1001_PORT 139 53 #define RFC1001_PORT 139
54 54
55 /* SMB echo "timeout" -- FIXME: tunable? */ 55 /* SMB echo "timeout" -- FIXME: tunable? */
56 #define SMB_ECHO_INTERVAL (60 * HZ) 56 #define SMB_ECHO_INTERVAL (60 * HZ)
57 57
58 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
59 unsigned char *p24);
60
61 extern mempool_t *cifs_req_poolp; 58 extern mempool_t *cifs_req_poolp;
62 59
63 struct smb_vol { 60 struct smb_vol {
64 char *username; 61 char *username;
65 char *password; 62 char *password;
66 char *domainname; 63 char *domainname;
67 char *UNC; 64 char *UNC;
68 char *UNCip; 65 char *UNCip;
69 char *iocharset; /* local code page for mapping to and from Unicode */ 66 char *iocharset; /* local code page for mapping to and from Unicode */
70 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ 67 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
71 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ 68 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
72 uid_t cred_uid; 69 uid_t cred_uid;
73 uid_t linux_uid; 70 uid_t linux_uid;
74 gid_t linux_gid; 71 gid_t linux_gid;
75 mode_t file_mode; 72 mode_t file_mode;
76 mode_t dir_mode; 73 mode_t dir_mode;
77 unsigned secFlg; 74 unsigned secFlg;
78 bool retry:1; 75 bool retry:1;
79 bool intr:1; 76 bool intr:1;
80 bool setuids:1; 77 bool setuids:1;
81 bool override_uid:1; 78 bool override_uid:1;
82 bool override_gid:1; 79 bool override_gid:1;
83 bool dynperm:1; 80 bool dynperm:1;
84 bool noperm:1; 81 bool noperm:1;
85 bool no_psx_acl:1; /* set if posix acl support should be disabled */ 82 bool no_psx_acl:1; /* set if posix acl support should be disabled */
86 bool cifs_acl:1; 83 bool cifs_acl:1;
87 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ 84 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
88 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 85 bool server_ino:1; /* use inode numbers from server ie UniqueId */
89 bool direct_io:1; 86 bool direct_io:1;
90 bool strict_io:1; /* strict cache behavior */ 87 bool strict_io:1; /* strict cache behavior */
91 bool remap:1; /* set to remap seven reserved chars in filenames */ 88 bool remap:1; /* set to remap seven reserved chars in filenames */
92 bool posix_paths:1; /* unset to not ask for posix pathnames. */ 89 bool posix_paths:1; /* unset to not ask for posix pathnames. */
93 bool no_linux_ext:1; 90 bool no_linux_ext:1;
94 bool sfu_emul:1; 91 bool sfu_emul:1;
95 bool nullauth:1; /* attempt to authenticate with null user */ 92 bool nullauth:1; /* attempt to authenticate with null user */
96 bool nocase:1; /* request case insensitive filenames */ 93 bool nocase:1; /* request case insensitive filenames */
97 bool nobrl:1; /* disable sending byte range locks to srv */ 94 bool nobrl:1; /* disable sending byte range locks to srv */
98 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */ 95 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
99 bool seal:1; /* request transport encryption on share */ 96 bool seal:1; /* request transport encryption on share */
100 bool nodfs:1; /* Do not request DFS, even if available */ 97 bool nodfs:1; /* Do not request DFS, even if available */
101 bool local_lease:1; /* check leases only on local system, not remote */ 98 bool local_lease:1; /* check leases only on local system, not remote */
102 bool noblocksnd:1; 99 bool noblocksnd:1;
103 bool noautotune:1; 100 bool noautotune:1;
104 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ 101 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
105 bool fsc:1; /* enable fscache */ 102 bool fsc:1; /* enable fscache */
106 bool mfsymlinks:1; /* use Minshall+French Symlinks */ 103 bool mfsymlinks:1; /* use Minshall+French Symlinks */
107 bool multiuser:1; 104 bool multiuser:1;
108 unsigned int rsize; 105 unsigned int rsize;
109 unsigned int wsize; 106 unsigned int wsize;
110 bool sockopt_tcp_nodelay:1; 107 bool sockopt_tcp_nodelay:1;
111 unsigned short int port; 108 unsigned short int port;
112 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 109 unsigned long actimeo; /* attribute cache timeout (jiffies) */
113 char *prepath; 110 char *prepath;
114 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 111 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
115 struct nls_table *local_nls; 112 struct nls_table *local_nls;
116 }; 113 };
117 114
118 /* FIXME: should these be tunable? */ 115 /* FIXME: should these be tunable? */
119 #define TLINK_ERROR_EXPIRE (1 * HZ) 116 #define TLINK_ERROR_EXPIRE (1 * HZ)
120 #define TLINK_IDLE_EXPIRE (600 * HZ) 117 #define TLINK_IDLE_EXPIRE (600 * HZ)
121 118
122 static int ip_connect(struct TCP_Server_Info *server); 119 static int ip_connect(struct TCP_Server_Info *server);
123 static int generic_ip_connect(struct TCP_Server_Info *server); 120 static int generic_ip_connect(struct TCP_Server_Info *server);
124 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); 121 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
125 static void cifs_prune_tlinks(struct work_struct *work); 122 static void cifs_prune_tlinks(struct work_struct *work);
126 123
127 /* 124 /*
128 * cifs tcp session reconnection 125 * cifs tcp session reconnection
129 * 126 *
130 * mark tcp session as reconnecting so temporarily locked 127 * mark tcp session as reconnecting so temporarily locked
131 * mark all smb sessions as reconnecting for tcp session 128 * mark all smb sessions as reconnecting for tcp session
132 * reconnect tcp session 129 * reconnect tcp session
133 * wake up waiters on reconnection? - (not needed currently) 130 * wake up waiters on reconnection? - (not needed currently)
134 */ 131 */
135 static int 132 static int
136 cifs_reconnect(struct TCP_Server_Info *server) 133 cifs_reconnect(struct TCP_Server_Info *server)
137 { 134 {
138 int rc = 0; 135 int rc = 0;
139 struct list_head *tmp, *tmp2; 136 struct list_head *tmp, *tmp2;
140 struct cifsSesInfo *ses; 137 struct cifsSesInfo *ses;
141 struct cifsTconInfo *tcon; 138 struct cifsTconInfo *tcon;
142 struct mid_q_entry *mid_entry; 139 struct mid_q_entry *mid_entry;
143 140
144 spin_lock(&GlobalMid_Lock); 141 spin_lock(&GlobalMid_Lock);
145 if (server->tcpStatus == CifsExiting) { 142 if (server->tcpStatus == CifsExiting) {
146 /* the demux thread will exit normally 143 /* the demux thread will exit normally
147 next time through the loop */ 144 next time through the loop */
148 spin_unlock(&GlobalMid_Lock); 145 spin_unlock(&GlobalMid_Lock);
149 return rc; 146 return rc;
150 } else 147 } else
151 server->tcpStatus = CifsNeedReconnect; 148 server->tcpStatus = CifsNeedReconnect;
152 spin_unlock(&GlobalMid_Lock); 149 spin_unlock(&GlobalMid_Lock);
153 server->maxBuf = 0; 150 server->maxBuf = 0;
154 151
155 cFYI(1, "Reconnecting tcp session"); 152 cFYI(1, "Reconnecting tcp session");
156 153
157 /* before reconnecting the tcp session, mark the smb session (uid) 154 /* before reconnecting the tcp session, mark the smb session (uid)
158 and the tid bad so they are not used until reconnected */ 155 and the tid bad so they are not used until reconnected */
159 cFYI(1, "%s: marking sessions and tcons for reconnect", __func__); 156 cFYI(1, "%s: marking sessions and tcons for reconnect", __func__);
160 spin_lock(&cifs_tcp_ses_lock); 157 spin_lock(&cifs_tcp_ses_lock);
161 list_for_each(tmp, &server->smb_ses_list) { 158 list_for_each(tmp, &server->smb_ses_list) {
162 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 159 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
163 ses->need_reconnect = true; 160 ses->need_reconnect = true;
164 ses->ipc_tid = 0; 161 ses->ipc_tid = 0;
165 list_for_each(tmp2, &ses->tcon_list) { 162 list_for_each(tmp2, &ses->tcon_list) {
166 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list); 163 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
167 tcon->need_reconnect = true; 164 tcon->need_reconnect = true;
168 } 165 }
169 } 166 }
170 spin_unlock(&cifs_tcp_ses_lock); 167 spin_unlock(&cifs_tcp_ses_lock);
171 168
172 /* do not want to be sending data on a socket we are freeing */ 169 /* do not want to be sending data on a socket we are freeing */
173 cFYI(1, "%s: tearing down socket", __func__); 170 cFYI(1, "%s: tearing down socket", __func__);
174 mutex_lock(&server->srv_mutex); 171 mutex_lock(&server->srv_mutex);
175 if (server->ssocket) { 172 if (server->ssocket) {
176 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state, 173 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
177 server->ssocket->flags); 174 server->ssocket->flags);
178 kernel_sock_shutdown(server->ssocket, SHUT_WR); 175 kernel_sock_shutdown(server->ssocket, SHUT_WR);
179 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx", 176 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
180 server->ssocket->state, 177 server->ssocket->state,
181 server->ssocket->flags); 178 server->ssocket->flags);
182 sock_release(server->ssocket); 179 sock_release(server->ssocket);
183 server->ssocket = NULL; 180 server->ssocket = NULL;
184 } 181 }
185 server->sequence_number = 0; 182 server->sequence_number = 0;
186 server->session_estab = false; 183 server->session_estab = false;
187 kfree(server->session_key.response); 184 kfree(server->session_key.response);
188 server->session_key.response = NULL; 185 server->session_key.response = NULL;
189 server->session_key.len = 0; 186 server->session_key.len = 0;
190 server->lstrp = jiffies; 187 server->lstrp = jiffies;
191 mutex_unlock(&server->srv_mutex); 188 mutex_unlock(&server->srv_mutex);
192 189
193 /* mark submitted MIDs for retry and issue callback */ 190 /* mark submitted MIDs for retry and issue callback */
194 cFYI(1, "%s: issuing mid callbacks", __func__); 191 cFYI(1, "%s: issuing mid callbacks", __func__);
195 spin_lock(&GlobalMid_Lock); 192 spin_lock(&GlobalMid_Lock);
196 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 193 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
197 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 194 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
198 if (mid_entry->midState == MID_REQUEST_SUBMITTED) 195 if (mid_entry->midState == MID_REQUEST_SUBMITTED)
199 mid_entry->midState = MID_RETRY_NEEDED; 196 mid_entry->midState = MID_RETRY_NEEDED;
200 list_del_init(&mid_entry->qhead); 197 list_del_init(&mid_entry->qhead);
201 mid_entry->callback(mid_entry); 198 mid_entry->callback(mid_entry);
202 } 199 }
203 spin_unlock(&GlobalMid_Lock); 200 spin_unlock(&GlobalMid_Lock);
204 201
205 while ((server->tcpStatus != CifsExiting) && 202 while ((server->tcpStatus != CifsExiting) &&
206 (server->tcpStatus != CifsGood)) { 203 (server->tcpStatus != CifsGood)) {
207 try_to_freeze(); 204 try_to_freeze();
208 205
209 /* we should try only the port we connected to before */ 206 /* we should try only the port we connected to before */
210 rc = generic_ip_connect(server); 207 rc = generic_ip_connect(server);
211 if (rc) { 208 if (rc) {
212 cFYI(1, "reconnect error %d", rc); 209 cFYI(1, "reconnect error %d", rc);
213 msleep(3000); 210 msleep(3000);
214 } else { 211 } else {
215 atomic_inc(&tcpSesReconnectCount); 212 atomic_inc(&tcpSesReconnectCount);
216 spin_lock(&GlobalMid_Lock); 213 spin_lock(&GlobalMid_Lock);
217 if (server->tcpStatus != CifsExiting) 214 if (server->tcpStatus != CifsExiting)
218 server->tcpStatus = CifsGood; 215 server->tcpStatus = CifsGood;
219 spin_unlock(&GlobalMid_Lock); 216 spin_unlock(&GlobalMid_Lock);
220 } 217 }
221 } 218 }
222 219
223 return rc; 220 return rc;
224 } 221 }
225 222
226 /* 223 /*
227 return codes: 224 return codes:
228 0 not a transact2, or all data present 225 0 not a transact2, or all data present
229 >0 transact2 with that much data missing 226 >0 transact2 with that much data missing
230 -EINVAL = invalid transact2 227 -EINVAL = invalid transact2
231 228
232 */ 229 */
233 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize) 230 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
234 { 231 {
235 struct smb_t2_rsp *pSMBt; 232 struct smb_t2_rsp *pSMBt;
236 int remaining; 233 int remaining;
237 __u16 total_data_size, data_in_this_rsp; 234 __u16 total_data_size, data_in_this_rsp;
238 235
239 if (pSMB->Command != SMB_COM_TRANSACTION2) 236 if (pSMB->Command != SMB_COM_TRANSACTION2)
240 return 0; 237 return 0;
241 238
242 /* check for plausible wct, bcc and t2 data and parm sizes */ 239 /* check for plausible wct, bcc and t2 data and parm sizes */
243 /* check for parm and data offset going beyond end of smb */ 240 /* check for parm and data offset going beyond end of smb */
244 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */ 241 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
245 cFYI(1, "invalid transact2 word count"); 242 cFYI(1, "invalid transact2 word count");
246 return -EINVAL; 243 return -EINVAL;
247 } 244 }
248 245
249 pSMBt = (struct smb_t2_rsp *)pSMB; 246 pSMBt = (struct smb_t2_rsp *)pSMB;
250 247
251 total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount); 248 total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
252 data_in_this_rsp = get_unaligned_le16(&pSMBt->t2_rsp.DataCount); 249 data_in_this_rsp = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
253 250
254 remaining = total_data_size - data_in_this_rsp; 251 remaining = total_data_size - data_in_this_rsp;
255 252
256 if (remaining == 0) 253 if (remaining == 0)
257 return 0; 254 return 0;
258 else if (remaining < 0) { 255 else if (remaining < 0) {
259 cFYI(1, "total data %d smaller than data in frame %d", 256 cFYI(1, "total data %d smaller than data in frame %d",
260 total_data_size, data_in_this_rsp); 257 total_data_size, data_in_this_rsp);
261 return -EINVAL; 258 return -EINVAL;
262 } else { 259 } else {
263 cFYI(1, "missing %d bytes from transact2, check next response", 260 cFYI(1, "missing %d bytes from transact2, check next response",
264 remaining); 261 remaining);
265 if (total_data_size > maxBufSize) { 262 if (total_data_size > maxBufSize) {
266 cERROR(1, "TotalDataSize %d is over maximum buffer %d", 263 cERROR(1, "TotalDataSize %d is over maximum buffer %d",
267 total_data_size, maxBufSize); 264 total_data_size, maxBufSize);
268 return -EINVAL; 265 return -EINVAL;
269 } 266 }
270 return remaining; 267 return remaining;
271 } 268 }
272 } 269 }
273 270
274 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB) 271 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
275 { 272 {
276 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond; 273 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
277 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB; 274 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
278 char *data_area_of_target; 275 char *data_area_of_target;
279 char *data_area_of_buf2; 276 char *data_area_of_buf2;
280 int remaining; 277 int remaining;
281 __u16 byte_count, total_data_size, total_in_buf, total_in_buf2; 278 __u16 byte_count, total_data_size, total_in_buf, total_in_buf2;
282 279
283 total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount); 280 total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
284 281
285 if (total_data_size != 282 if (total_data_size !=
286 get_unaligned_le16(&pSMB2->t2_rsp.TotalDataCount)) 283 get_unaligned_le16(&pSMB2->t2_rsp.TotalDataCount))
287 cFYI(1, "total data size of primary and secondary t2 differ"); 284 cFYI(1, "total data size of primary and secondary t2 differ");
288 285
289 total_in_buf = get_unaligned_le16(&pSMBt->t2_rsp.DataCount); 286 total_in_buf = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
290 287
291 remaining = total_data_size - total_in_buf; 288 remaining = total_data_size - total_in_buf;
292 289
293 if (remaining < 0) 290 if (remaining < 0)
294 return -EINVAL; 291 return -EINVAL;
295 292
296 if (remaining == 0) /* nothing to do, ignore */ 293 if (remaining == 0) /* nothing to do, ignore */
297 return 0; 294 return 0;
298 295
299 total_in_buf2 = get_unaligned_le16(&pSMB2->t2_rsp.DataCount); 296 total_in_buf2 = get_unaligned_le16(&pSMB2->t2_rsp.DataCount);
300 if (remaining < total_in_buf2) { 297 if (remaining < total_in_buf2) {
301 cFYI(1, "transact2 2nd response contains too much data"); 298 cFYI(1, "transact2 2nd response contains too much data");
302 } 299 }
303 300
304 /* find end of first SMB data area */ 301 /* find end of first SMB data area */
305 data_area_of_target = (char *)&pSMBt->hdr.Protocol + 302 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
306 get_unaligned_le16(&pSMBt->t2_rsp.DataOffset); 303 get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
307 /* validate target area */ 304 /* validate target area */
308 305
309 data_area_of_buf2 = (char *)&pSMB2->hdr.Protocol + 306 data_area_of_buf2 = (char *)&pSMB2->hdr.Protocol +
310 get_unaligned_le16(&pSMB2->t2_rsp.DataOffset); 307 get_unaligned_le16(&pSMB2->t2_rsp.DataOffset);
311 308
312 data_area_of_target += total_in_buf; 309 data_area_of_target += total_in_buf;
313 310
314 /* copy second buffer into end of first buffer */ 311 /* copy second buffer into end of first buffer */
315 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2); 312 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
316 total_in_buf += total_in_buf2; 313 total_in_buf += total_in_buf2;
317 put_unaligned_le16(total_in_buf, &pSMBt->t2_rsp.DataCount); 314 put_unaligned_le16(total_in_buf, &pSMBt->t2_rsp.DataCount);
318 byte_count = get_bcc_le(pTargetSMB); 315 byte_count = get_bcc_le(pTargetSMB);
319 byte_count += total_in_buf2; 316 byte_count += total_in_buf2;
320 put_bcc_le(byte_count, pTargetSMB); 317 put_bcc_le(byte_count, pTargetSMB);
321 318
322 byte_count = pTargetSMB->smb_buf_length; 319 byte_count = pTargetSMB->smb_buf_length;
323 byte_count += total_in_buf2; 320 byte_count += total_in_buf2;
324 321
325 /* BB also add check that we are not beyond maximum buffer size */ 322 /* BB also add check that we are not beyond maximum buffer size */
326 323
327 pTargetSMB->smb_buf_length = byte_count; 324 pTargetSMB->smb_buf_length = byte_count;
328 325
329 if (remaining == total_in_buf2) { 326 if (remaining == total_in_buf2) {
330 cFYI(1, "found the last secondary response"); 327 cFYI(1, "found the last secondary response");
331 return 0; /* we are done */ 328 return 0; /* we are done */
332 } else /* more responses to go */ 329 } else /* more responses to go */
333 return 1; 330 return 1;
334 } 331 }
335 332
336 static void 333 static void
337 cifs_echo_request(struct work_struct *work) 334 cifs_echo_request(struct work_struct *work)
338 { 335 {
339 int rc; 336 int rc;
340 struct TCP_Server_Info *server = container_of(work, 337 struct TCP_Server_Info *server = container_of(work,
341 struct TCP_Server_Info, echo.work); 338 struct TCP_Server_Info, echo.work);
342 339
343 /* no need to ping if we got a response recently */ 340 /* no need to ping if we got a response recently */
344 if (time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) 341 if (time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
345 goto requeue_echo; 342 goto requeue_echo;
346 343
347 rc = CIFSSMBEcho(server); 344 rc = CIFSSMBEcho(server);
348 if (rc) 345 if (rc)
349 cFYI(1, "Unable to send echo request to server: %s", 346 cFYI(1, "Unable to send echo request to server: %s",
350 server->hostname); 347 server->hostname);
351 348
352 requeue_echo: 349 requeue_echo:
353 queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL); 350 queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL);
354 } 351 }
355 352
356 static int 353 static int
357 cifs_demultiplex_thread(struct TCP_Server_Info *server) 354 cifs_demultiplex_thread(struct TCP_Server_Info *server)
358 { 355 {
359 int length; 356 int length;
360 unsigned int pdu_length, total_read; 357 unsigned int pdu_length, total_read;
361 struct smb_hdr *smb_buffer = NULL; 358 struct smb_hdr *smb_buffer = NULL;
362 struct smb_hdr *bigbuf = NULL; 359 struct smb_hdr *bigbuf = NULL;
363 struct smb_hdr *smallbuf = NULL; 360 struct smb_hdr *smallbuf = NULL;
364 struct msghdr smb_msg; 361 struct msghdr smb_msg;
365 struct kvec iov; 362 struct kvec iov;
366 struct socket *csocket = server->ssocket; 363 struct socket *csocket = server->ssocket;
367 struct list_head *tmp, *tmp2; 364 struct list_head *tmp, *tmp2;
368 struct task_struct *task_to_wake = NULL; 365 struct task_struct *task_to_wake = NULL;
369 struct mid_q_entry *mid_entry; 366 struct mid_q_entry *mid_entry;
370 char temp; 367 char temp;
371 bool isLargeBuf = false; 368 bool isLargeBuf = false;
372 bool isMultiRsp; 369 bool isMultiRsp;
373 int reconnect; 370 int reconnect;
374 371
375 current->flags |= PF_MEMALLOC; 372 current->flags |= PF_MEMALLOC;
376 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current)); 373 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
377 374
378 length = atomic_inc_return(&tcpSesAllocCount); 375 length = atomic_inc_return(&tcpSesAllocCount);
379 if (length > 1) 376 if (length > 1)
380 mempool_resize(cifs_req_poolp, length + cifs_min_rcv, 377 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
381 GFP_KERNEL); 378 GFP_KERNEL);
382 379
383 set_freezable(); 380 set_freezable();
384 while (server->tcpStatus != CifsExiting) { 381 while (server->tcpStatus != CifsExiting) {
385 if (try_to_freeze()) 382 if (try_to_freeze())
386 continue; 383 continue;
387 if (bigbuf == NULL) { 384 if (bigbuf == NULL) {
388 bigbuf = cifs_buf_get(); 385 bigbuf = cifs_buf_get();
389 if (!bigbuf) { 386 if (!bigbuf) {
390 cERROR(1, "No memory for large SMB response"); 387 cERROR(1, "No memory for large SMB response");
391 msleep(3000); 388 msleep(3000);
392 /* retry will check if exiting */ 389 /* retry will check if exiting */
393 continue; 390 continue;
394 } 391 }
395 } else if (isLargeBuf) { 392 } else if (isLargeBuf) {
396 /* we are reusing a dirty large buf, clear its start */ 393 /* we are reusing a dirty large buf, clear its start */
397 memset(bigbuf, 0, sizeof(struct smb_hdr)); 394 memset(bigbuf, 0, sizeof(struct smb_hdr));
398 } 395 }
399 396
400 if (smallbuf == NULL) { 397 if (smallbuf == NULL) {
401 smallbuf = cifs_small_buf_get(); 398 smallbuf = cifs_small_buf_get();
402 if (!smallbuf) { 399 if (!smallbuf) {
403 cERROR(1, "No memory for SMB response"); 400 cERROR(1, "No memory for SMB response");
404 msleep(1000); 401 msleep(1000);
405 /* retry will check if exiting */ 402 /* retry will check if exiting */
406 continue; 403 continue;
407 } 404 }
408 /* beginning of smb buffer is cleared in our buf_get */ 405 /* beginning of smb buffer is cleared in our buf_get */
409 } else /* if existing small buf clear beginning */ 406 } else /* if existing small buf clear beginning */
410 memset(smallbuf, 0, sizeof(struct smb_hdr)); 407 memset(smallbuf, 0, sizeof(struct smb_hdr));
411 408
412 isLargeBuf = false; 409 isLargeBuf = false;
413 isMultiRsp = false; 410 isMultiRsp = false;
414 smb_buffer = smallbuf; 411 smb_buffer = smallbuf;
415 iov.iov_base = smb_buffer; 412 iov.iov_base = smb_buffer;
416 iov.iov_len = 4; 413 iov.iov_len = 4;
417 smb_msg.msg_control = NULL; 414 smb_msg.msg_control = NULL;
418 smb_msg.msg_controllen = 0; 415 smb_msg.msg_controllen = 0;
419 pdu_length = 4; /* enough to get RFC1001 header */ 416 pdu_length = 4; /* enough to get RFC1001 header */
420 417
421 incomplete_rcv: 418 incomplete_rcv:
422 if (echo_retries > 0 && 419 if (echo_retries > 0 &&
423 time_after(jiffies, server->lstrp + 420 time_after(jiffies, server->lstrp +
424 (echo_retries * SMB_ECHO_INTERVAL))) { 421 (echo_retries * SMB_ECHO_INTERVAL))) {
425 cERROR(1, "Server %s has not responded in %d seconds. " 422 cERROR(1, "Server %s has not responded in %d seconds. "
426 "Reconnecting...", server->hostname, 423 "Reconnecting...", server->hostname,
427 (echo_retries * SMB_ECHO_INTERVAL / HZ)); 424 (echo_retries * SMB_ECHO_INTERVAL / HZ));
428 cifs_reconnect(server); 425 cifs_reconnect(server);
429 csocket = server->ssocket; 426 csocket = server->ssocket;
430 wake_up(&server->response_q); 427 wake_up(&server->response_q);
431 continue; 428 continue;
432 } 429 }
433 430
434 length = 431 length =
435 kernel_recvmsg(csocket, &smb_msg, 432 kernel_recvmsg(csocket, &smb_msg,
436 &iov, 1, pdu_length, 0 /* BB other flags? */); 433 &iov, 1, pdu_length, 0 /* BB other flags? */);
437 434
438 if (server->tcpStatus == CifsExiting) { 435 if (server->tcpStatus == CifsExiting) {
439 break; 436 break;
440 } else if (server->tcpStatus == CifsNeedReconnect) { 437 } else if (server->tcpStatus == CifsNeedReconnect) {
441 cFYI(1, "Reconnect after server stopped responding"); 438 cFYI(1, "Reconnect after server stopped responding");
442 cifs_reconnect(server); 439 cifs_reconnect(server);
443 cFYI(1, "call to reconnect done"); 440 cFYI(1, "call to reconnect done");
444 csocket = server->ssocket; 441 csocket = server->ssocket;
445 continue; 442 continue;
446 } else if (length == -ERESTARTSYS || 443 } else if (length == -ERESTARTSYS ||
447 length == -EAGAIN || 444 length == -EAGAIN ||
448 length == -EINTR) { 445 length == -EINTR) {
449 msleep(1); /* minimum sleep to prevent looping 446 msleep(1); /* minimum sleep to prevent looping
450 allowing socket to clear and app threads to set 447 allowing socket to clear and app threads to set
451 tcpStatus CifsNeedReconnect if server hung */ 448 tcpStatus CifsNeedReconnect if server hung */
452 if (pdu_length < 4) { 449 if (pdu_length < 4) {
453 iov.iov_base = (4 - pdu_length) + 450 iov.iov_base = (4 - pdu_length) +
454 (char *)smb_buffer; 451 (char *)smb_buffer;
455 iov.iov_len = pdu_length; 452 iov.iov_len = pdu_length;
456 smb_msg.msg_control = NULL; 453 smb_msg.msg_control = NULL;
457 smb_msg.msg_controllen = 0; 454 smb_msg.msg_controllen = 0;
458 goto incomplete_rcv; 455 goto incomplete_rcv;
459 } else 456 } else
460 continue; 457 continue;
461 } else if (length <= 0) { 458 } else if (length <= 0) {
462 cFYI(1, "Reconnect after unexpected peek error %d", 459 cFYI(1, "Reconnect after unexpected peek error %d",
463 length); 460 length);
464 cifs_reconnect(server); 461 cifs_reconnect(server);
465 csocket = server->ssocket; 462 csocket = server->ssocket;
466 wake_up(&server->response_q); 463 wake_up(&server->response_q);
467 continue; 464 continue;
468 } else if (length < pdu_length) { 465 } else if (length < pdu_length) {
469 cFYI(1, "requested %d bytes but only got %d bytes", 466 cFYI(1, "requested %d bytes but only got %d bytes",
470 pdu_length, length); 467 pdu_length, length);
471 pdu_length -= length; 468 pdu_length -= length;
472 msleep(1); 469 msleep(1);
473 goto incomplete_rcv; 470 goto incomplete_rcv;
474 } 471 }
475 472
476 /* The right amount was read from socket - 4 bytes */ 473 /* The right amount was read from socket - 4 bytes */
477 /* so we can now interpret the length field */ 474 /* so we can now interpret the length field */
478 475
479 /* the first byte big endian of the length field, 476 /* the first byte big endian of the length field,
480 is actually not part of the length but the type 477 is actually not part of the length but the type
481 with the most common, zero, as regular data */ 478 with the most common, zero, as regular data */
482 temp = *((char *) smb_buffer); 479 temp = *((char *) smb_buffer);
483 480
484 /* Note that FC 1001 length is big endian on the wire, 481 /* Note that FC 1001 length is big endian on the wire,
485 but we convert it here so it is always manipulated 482 but we convert it here so it is always manipulated
486 as host byte order */ 483 as host byte order */
487 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length); 484 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
488 smb_buffer->smb_buf_length = pdu_length; 485 smb_buffer->smb_buf_length = pdu_length;
489 486
490 cFYI(1, "rfc1002 length 0x%x", pdu_length+4); 487 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
491 488
492 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) { 489 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
493 continue; 490 continue;
494 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { 491 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
495 cFYI(1, "Good RFC 1002 session rsp"); 492 cFYI(1, "Good RFC 1002 session rsp");
496 continue; 493 continue;
497 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 494 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
498 /* we get this from Windows 98 instead of 495 /* we get this from Windows 98 instead of
499 an error on SMB negprot response */ 496 an error on SMB negprot response */
500 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", 497 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
501 pdu_length); 498 pdu_length);
502 /* give server a second to clean up */ 499 /* give server a second to clean up */
503 msleep(1000); 500 msleep(1000);
504 /* always try 445 first on reconnect since we get NACK 501 /* always try 445 first on reconnect since we get NACK
505 * on some if we ever connected to port 139 (the NACK 502 * on some if we ever connected to port 139 (the NACK
506 * is since we do not begin with RFC1001 session 503 * is since we do not begin with RFC1001 session
507 * initialize frame) 504 * initialize frame)
508 */ 505 */
509 cifs_set_port((struct sockaddr *) 506 cifs_set_port((struct sockaddr *)
510 &server->dstaddr, CIFS_PORT); 507 &server->dstaddr, CIFS_PORT);
511 cifs_reconnect(server); 508 cifs_reconnect(server);
512 csocket = server->ssocket; 509 csocket = server->ssocket;
513 wake_up(&server->response_q); 510 wake_up(&server->response_q);
514 continue; 511 continue;
515 } else if (temp != (char) 0) { 512 } else if (temp != (char) 0) {
516 cERROR(1, "Unknown RFC 1002 frame"); 513 cERROR(1, "Unknown RFC 1002 frame");
517 cifs_dump_mem(" Received Data: ", (char *)smb_buffer, 514 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
518 length); 515 length);
519 cifs_reconnect(server); 516 cifs_reconnect(server);
520 csocket = server->ssocket; 517 csocket = server->ssocket;
521 continue; 518 continue;
522 } 519 }
523 520
524 /* else we have an SMB response */ 521 /* else we have an SMB response */
525 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || 522 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
526 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) { 523 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
527 cERROR(1, "Invalid size SMB length %d pdu_length %d", 524 cERROR(1, "Invalid size SMB length %d pdu_length %d",
528 length, pdu_length+4); 525 length, pdu_length+4);
529 cifs_reconnect(server); 526 cifs_reconnect(server);
530 csocket = server->ssocket; 527 csocket = server->ssocket;
531 wake_up(&server->response_q); 528 wake_up(&server->response_q);
532 continue; 529 continue;
533 } 530 }
534 531
535 /* else length ok */ 532 /* else length ok */
536 reconnect = 0; 533 reconnect = 0;
537 534
538 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { 535 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
539 isLargeBuf = true; 536 isLargeBuf = true;
540 memcpy(bigbuf, smallbuf, 4); 537 memcpy(bigbuf, smallbuf, 4);
541 smb_buffer = bigbuf; 538 smb_buffer = bigbuf;
542 } 539 }
543 length = 0; 540 length = 0;
544 iov.iov_base = 4 + (char *)smb_buffer; 541 iov.iov_base = 4 + (char *)smb_buffer;
545 iov.iov_len = pdu_length; 542 iov.iov_len = pdu_length;
546 for (total_read = 0; total_read < pdu_length; 543 for (total_read = 0; total_read < pdu_length;
547 total_read += length) { 544 total_read += length) {
548 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, 545 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
549 pdu_length - total_read, 0); 546 pdu_length - total_read, 0);
550 if (server->tcpStatus == CifsExiting) { 547 if (server->tcpStatus == CifsExiting) {
551 /* then will exit */ 548 /* then will exit */
552 reconnect = 2; 549 reconnect = 2;
553 break; 550 break;
554 } else if (server->tcpStatus == CifsNeedReconnect) { 551 } else if (server->tcpStatus == CifsNeedReconnect) {
555 cifs_reconnect(server); 552 cifs_reconnect(server);
556 csocket = server->ssocket; 553 csocket = server->ssocket;
557 /* Reconnect wakes up rspns q */ 554 /* Reconnect wakes up rspns q */
558 /* Now we will reread sock */ 555 /* Now we will reread sock */
559 reconnect = 1; 556 reconnect = 1;
560 break; 557 break;
561 } else if (length == -ERESTARTSYS || 558 } else if (length == -ERESTARTSYS ||
562 length == -EAGAIN || 559 length == -EAGAIN ||
563 length == -EINTR) { 560 length == -EINTR) {
564 msleep(1); /* minimum sleep to prevent looping, 561 msleep(1); /* minimum sleep to prevent looping,
565 allowing socket to clear and app 562 allowing socket to clear and app
566 threads to set tcpStatus 563 threads to set tcpStatus
567 CifsNeedReconnect if server hung*/ 564 CifsNeedReconnect if server hung*/
568 length = 0; 565 length = 0;
569 continue; 566 continue;
570 } else if (length <= 0) { 567 } else if (length <= 0) {
571 cERROR(1, "Received no data, expecting %d", 568 cERROR(1, "Received no data, expecting %d",
572 pdu_length - total_read); 569 pdu_length - total_read);
573 cifs_reconnect(server); 570 cifs_reconnect(server);
574 csocket = server->ssocket; 571 csocket = server->ssocket;
575 reconnect = 1; 572 reconnect = 1;
576 break; 573 break;
577 } 574 }
578 } 575 }
579 if (reconnect == 2) 576 if (reconnect == 2)
580 break; 577 break;
581 else if (reconnect == 1) 578 else if (reconnect == 1)
582 continue; 579 continue;
583 580
584 length += 4; /* account for rfc1002 hdr */ 581 length += 4; /* account for rfc1002 hdr */
585 582
586 583
587 dump_smb(smb_buffer, length); 584 dump_smb(smb_buffer, length);
588 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { 585 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
589 cifs_dump_mem("Bad SMB: ", smb_buffer, 48); 586 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
590 continue; 587 continue;
591 } 588 }
592 589
593 mid_entry = NULL; 590 mid_entry = NULL;
594 server->lstrp = jiffies; 591 server->lstrp = jiffies;
595 592
596 spin_lock(&GlobalMid_Lock); 593 spin_lock(&GlobalMid_Lock);
597 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 594 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
598 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 595 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
599 596
600 if ((mid_entry->mid == smb_buffer->Mid) && 597 if ((mid_entry->mid == smb_buffer->Mid) &&
601 (mid_entry->midState == MID_REQUEST_SUBMITTED) && 598 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
602 (mid_entry->command == smb_buffer->Command)) { 599 (mid_entry->command == smb_buffer->Command)) {
603 if (check2ndT2(smb_buffer,server->maxBuf) > 0) { 600 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
604 /* We have a multipart transact2 resp */ 601 /* We have a multipart transact2 resp */
605 isMultiRsp = true; 602 isMultiRsp = true;
606 if (mid_entry->resp_buf) { 603 if (mid_entry->resp_buf) {
607 /* merge response - fix up 1st*/ 604 /* merge response - fix up 1st*/
608 if (coalesce_t2(smb_buffer, 605 if (coalesce_t2(smb_buffer,
609 mid_entry->resp_buf)) { 606 mid_entry->resp_buf)) {
610 mid_entry->multiRsp = 607 mid_entry->multiRsp =
611 true; 608 true;
612 break; 609 break;
613 } else { 610 } else {
614 /* all parts received */ 611 /* all parts received */
615 mid_entry->multiEnd = 612 mid_entry->multiEnd =
616 true; 613 true;
617 goto multi_t2_fnd; 614 goto multi_t2_fnd;
618 } 615 }
619 } else { 616 } else {
620 if (!isLargeBuf) { 617 if (!isLargeBuf) {
621 cERROR(1, "1st trans2 resp needs bigbuf"); 618 cERROR(1, "1st trans2 resp needs bigbuf");
622 /* BB maybe we can fix this up, switch 619 /* BB maybe we can fix this up, switch
623 to already allocated large buffer? */ 620 to already allocated large buffer? */
624 } else { 621 } else {
625 /* Have first buffer */ 622 /* Have first buffer */
626 mid_entry->resp_buf = 623 mid_entry->resp_buf =
627 smb_buffer; 624 smb_buffer;
628 mid_entry->largeBuf = 625 mid_entry->largeBuf =
629 true; 626 true;
630 bigbuf = NULL; 627 bigbuf = NULL;
631 } 628 }
632 } 629 }
633 break; 630 break;
634 } 631 }
635 mid_entry->resp_buf = smb_buffer; 632 mid_entry->resp_buf = smb_buffer;
636 mid_entry->largeBuf = isLargeBuf; 633 mid_entry->largeBuf = isLargeBuf;
637 multi_t2_fnd: 634 multi_t2_fnd:
638 mid_entry->midState = MID_RESPONSE_RECEIVED; 635 mid_entry->midState = MID_RESPONSE_RECEIVED;
639 list_del_init(&mid_entry->qhead); 636 list_del_init(&mid_entry->qhead);
640 mid_entry->callback(mid_entry); 637 mid_entry->callback(mid_entry);
641 #ifdef CONFIG_CIFS_STATS2 638 #ifdef CONFIG_CIFS_STATS2
642 mid_entry->when_received = jiffies; 639 mid_entry->when_received = jiffies;
643 #endif 640 #endif
644 break; 641 break;
645 } 642 }
646 mid_entry = NULL; 643 mid_entry = NULL;
647 } 644 }
648 spin_unlock(&GlobalMid_Lock); 645 spin_unlock(&GlobalMid_Lock);
649 646
650 if (mid_entry != NULL) { 647 if (mid_entry != NULL) {
651 /* Was previous buf put in mpx struct for multi-rsp? */ 648 /* Was previous buf put in mpx struct for multi-rsp? */
652 if (!isMultiRsp) { 649 if (!isMultiRsp) {
653 /* smb buffer will be freed by user thread */ 650 /* smb buffer will be freed by user thread */
654 if (isLargeBuf) 651 if (isLargeBuf)
655 bigbuf = NULL; 652 bigbuf = NULL;
656 else 653 else
657 smallbuf = NULL; 654 smallbuf = NULL;
658 } 655 }
659 } else if (!is_valid_oplock_break(smb_buffer, server) && 656 } else if (!is_valid_oplock_break(smb_buffer, server) &&
660 !isMultiRsp) { 657 !isMultiRsp) {
661 cERROR(1, "No task to wake, unknown frame received! " 658 cERROR(1, "No task to wake, unknown frame received! "
662 "NumMids %d", atomic_read(&midCount)); 659 "NumMids %d", atomic_read(&midCount));
663 cifs_dump_mem("Received Data is: ", (char *)smb_buffer, 660 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
664 sizeof(struct smb_hdr)); 661 sizeof(struct smb_hdr));
665 #ifdef CONFIG_CIFS_DEBUG2 662 #ifdef CONFIG_CIFS_DEBUG2
666 cifs_dump_detail(smb_buffer); 663 cifs_dump_detail(smb_buffer);
667 cifs_dump_mids(server); 664 cifs_dump_mids(server);
668 #endif /* CIFS_DEBUG2 */ 665 #endif /* CIFS_DEBUG2 */
669 666
670 } 667 }
671 } /* end while !EXITING */ 668 } /* end while !EXITING */
672 669
673 /* take it off the list, if it's not already */ 670 /* take it off the list, if it's not already */
674 spin_lock(&cifs_tcp_ses_lock); 671 spin_lock(&cifs_tcp_ses_lock);
675 list_del_init(&server->tcp_ses_list); 672 list_del_init(&server->tcp_ses_list);
676 spin_unlock(&cifs_tcp_ses_lock); 673 spin_unlock(&cifs_tcp_ses_lock);
677 674
678 spin_lock(&GlobalMid_Lock); 675 spin_lock(&GlobalMid_Lock);
679 server->tcpStatus = CifsExiting; 676 server->tcpStatus = CifsExiting;
680 spin_unlock(&GlobalMid_Lock); 677 spin_unlock(&GlobalMid_Lock);
681 wake_up_all(&server->response_q); 678 wake_up_all(&server->response_q);
682 679
683 /* check if we have blocked requests that need to free */ 680 /* check if we have blocked requests that need to free */
684 /* Note that cifs_max_pending is normally 50, but 681 /* Note that cifs_max_pending is normally 50, but
685 can be set at module install time to as little as two */ 682 can be set at module install time to as little as two */
686 spin_lock(&GlobalMid_Lock); 683 spin_lock(&GlobalMid_Lock);
687 if (atomic_read(&server->inFlight) >= cifs_max_pending) 684 if (atomic_read(&server->inFlight) >= cifs_max_pending)
688 atomic_set(&server->inFlight, cifs_max_pending - 1); 685 atomic_set(&server->inFlight, cifs_max_pending - 1);
689 /* We do not want to set the max_pending too low or we 686 /* We do not want to set the max_pending too low or we
690 could end up with the counter going negative */ 687 could end up with the counter going negative */
691 spin_unlock(&GlobalMid_Lock); 688 spin_unlock(&GlobalMid_Lock);
692 /* Although there should not be any requests blocked on 689 /* Although there should not be any requests blocked on
693 this queue it can not hurt to be paranoid and try to wake up requests 690 this queue it can not hurt to be paranoid and try to wake up requests
694 that may haven been blocked when more than 50 at time were on the wire 691 that may haven been blocked when more than 50 at time were on the wire
695 to the same server - they now will see the session is in exit state 692 to the same server - they now will see the session is in exit state
696 and get out of SendReceive. */ 693 and get out of SendReceive. */
697 wake_up_all(&server->request_q); 694 wake_up_all(&server->request_q);
698 /* give those requests time to exit */ 695 /* give those requests time to exit */
699 msleep(125); 696 msleep(125);
700 697
701 if (server->ssocket) { 698 if (server->ssocket) {
702 sock_release(csocket); 699 sock_release(csocket);
703 server->ssocket = NULL; 700 server->ssocket = NULL;
704 } 701 }
705 /* buffer usuallly freed in free_mid - need to free it here on exit */ 702 /* buffer usuallly freed in free_mid - need to free it here on exit */
706 cifs_buf_release(bigbuf); 703 cifs_buf_release(bigbuf);
707 if (smallbuf) /* no sense logging a debug message if NULL */ 704 if (smallbuf) /* no sense logging a debug message if NULL */
708 cifs_small_buf_release(smallbuf); 705 cifs_small_buf_release(smallbuf);
709 706
710 if (!list_empty(&server->pending_mid_q)) { 707 if (!list_empty(&server->pending_mid_q)) {
711 spin_lock(&GlobalMid_Lock); 708 spin_lock(&GlobalMid_Lock);
712 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 709 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
713 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 710 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
714 cFYI(1, "Clearing Mid 0x%x - issuing callback", 711 cFYI(1, "Clearing Mid 0x%x - issuing callback",
715 mid_entry->mid); 712 mid_entry->mid);
716 list_del_init(&mid_entry->qhead); 713 list_del_init(&mid_entry->qhead);
717 mid_entry->callback(mid_entry); 714 mid_entry->callback(mid_entry);
718 } 715 }
719 spin_unlock(&GlobalMid_Lock); 716 spin_unlock(&GlobalMid_Lock);
720 /* 1/8th of sec is more than enough time for them to exit */ 717 /* 1/8th of sec is more than enough time for them to exit */
721 msleep(125); 718 msleep(125);
722 } 719 }
723 720
724 if (!list_empty(&server->pending_mid_q)) { 721 if (!list_empty(&server->pending_mid_q)) {
725 /* mpx threads have not exited yet give them 722 /* mpx threads have not exited yet give them
726 at least the smb send timeout time for long ops */ 723 at least the smb send timeout time for long ops */
727 /* due to delays on oplock break requests, we need 724 /* due to delays on oplock break requests, we need
728 to wait at least 45 seconds before giving up 725 to wait at least 45 seconds before giving up
729 on a request getting a response and going ahead 726 on a request getting a response and going ahead
730 and killing cifsd */ 727 and killing cifsd */
731 cFYI(1, "Wait for exit from demultiplex thread"); 728 cFYI(1, "Wait for exit from demultiplex thread");
732 msleep(46000); 729 msleep(46000);
733 /* if threads still have not exited they are probably never 730 /* if threads still have not exited they are probably never
734 coming home not much else we can do but free the memory */ 731 coming home not much else we can do but free the memory */
735 } 732 }
736 733
737 kfree(server->hostname); 734 kfree(server->hostname);
738 task_to_wake = xchg(&server->tsk, NULL); 735 task_to_wake = xchg(&server->tsk, NULL);
739 kfree(server); 736 kfree(server);
740 737
741 length = atomic_dec_return(&tcpSesAllocCount); 738 length = atomic_dec_return(&tcpSesAllocCount);
742 if (length > 0) 739 if (length > 0)
743 mempool_resize(cifs_req_poolp, length + cifs_min_rcv, 740 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
744 GFP_KERNEL); 741 GFP_KERNEL);
745 742
746 /* if server->tsk was NULL then wait for a signal before exiting */ 743 /* if server->tsk was NULL then wait for a signal before exiting */
747 if (!task_to_wake) { 744 if (!task_to_wake) {
748 set_current_state(TASK_INTERRUPTIBLE); 745 set_current_state(TASK_INTERRUPTIBLE);
749 while (!signal_pending(current)) { 746 while (!signal_pending(current)) {
750 schedule(); 747 schedule();
751 set_current_state(TASK_INTERRUPTIBLE); 748 set_current_state(TASK_INTERRUPTIBLE);
752 } 749 }
753 set_current_state(TASK_RUNNING); 750 set_current_state(TASK_RUNNING);
754 } 751 }
755 752
756 module_put_and_exit(0); 753 module_put_and_exit(0);
757 } 754 }
758 755
759 /* extract the host portion of the UNC string */ 756 /* extract the host portion of the UNC string */
760 static char * 757 static char *
761 extract_hostname(const char *unc) 758 extract_hostname(const char *unc)
762 { 759 {
763 const char *src; 760 const char *src;
764 char *dst, *delim; 761 char *dst, *delim;
765 unsigned int len; 762 unsigned int len;
766 763
767 /* skip double chars at beginning of string */ 764 /* skip double chars at beginning of string */
768 /* BB: check validity of these bytes? */ 765 /* BB: check validity of these bytes? */
769 src = unc + 2; 766 src = unc + 2;
770 767
771 /* delimiter between hostname and sharename is always '\\' now */ 768 /* delimiter between hostname and sharename is always '\\' now */
772 delim = strchr(src, '\\'); 769 delim = strchr(src, '\\');
773 if (!delim) 770 if (!delim)
774 return ERR_PTR(-EINVAL); 771 return ERR_PTR(-EINVAL);
775 772
776 len = delim - src; 773 len = delim - src;
777 dst = kmalloc((len + 1), GFP_KERNEL); 774 dst = kmalloc((len + 1), GFP_KERNEL);
778 if (dst == NULL) 775 if (dst == NULL)
779 return ERR_PTR(-ENOMEM); 776 return ERR_PTR(-ENOMEM);
780 777
781 memcpy(dst, src, len); 778 memcpy(dst, src, len);
782 dst[len] = '\0'; 779 dst[len] = '\0';
783 780
784 return dst; 781 return dst;
785 } 782 }
786 783
787 static int 784 static int
788 cifs_parse_mount_options(char *options, const char *devname, 785 cifs_parse_mount_options(char *options, const char *devname,
789 struct smb_vol *vol) 786 struct smb_vol *vol)
790 { 787 {
791 char *value; 788 char *value;
792 char *data; 789 char *data;
793 unsigned int temp_len, i, j; 790 unsigned int temp_len, i, j;
794 char separator[2]; 791 char separator[2];
795 short int override_uid = -1; 792 short int override_uid = -1;
796 short int override_gid = -1; 793 short int override_gid = -1;
797 bool uid_specified = false; 794 bool uid_specified = false;
798 bool gid_specified = false; 795 bool gid_specified = false;
799 char *nodename = utsname()->nodename; 796 char *nodename = utsname()->nodename;
800 797
801 separator[0] = ','; 798 separator[0] = ',';
802 separator[1] = 0; 799 separator[1] = 0;
803 800
804 /* 801 /*
805 * does not have to be perfect mapping since field is 802 * does not have to be perfect mapping since field is
806 * informational, only used for servers that do not support 803 * informational, only used for servers that do not support
807 * port 445 and it can be overridden at mount time 804 * port 445 and it can be overridden at mount time
808 */ 805 */
809 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); 806 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
810 for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++) 807 for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
811 vol->source_rfc1001_name[i] = toupper(nodename[i]); 808 vol->source_rfc1001_name[i] = toupper(nodename[i]);
812 809
813 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0; 810 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
814 /* null target name indicates to use *SMBSERVR default called name 811 /* null target name indicates to use *SMBSERVR default called name
815 if we end up sending RFC1001 session initialize */ 812 if we end up sending RFC1001 session initialize */
816 vol->target_rfc1001_name[0] = 0; 813 vol->target_rfc1001_name[0] = 0;
817 vol->cred_uid = current_uid(); 814 vol->cred_uid = current_uid();
818 vol->linux_uid = current_uid(); 815 vol->linux_uid = current_uid();
819 vol->linux_gid = current_gid(); 816 vol->linux_gid = current_gid();
820 817
821 /* default to only allowing write access to owner of the mount */ 818 /* default to only allowing write access to owner of the mount */
822 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; 819 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
823 820
824 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ 821 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
825 /* default is always to request posix paths. */ 822 /* default is always to request posix paths. */
826 vol->posix_paths = 1; 823 vol->posix_paths = 1;
827 /* default to using server inode numbers where available */ 824 /* default to using server inode numbers where available */
828 vol->server_ino = 1; 825 vol->server_ino = 1;
829 826
830 vol->actimeo = CIFS_DEF_ACTIMEO; 827 vol->actimeo = CIFS_DEF_ACTIMEO;
831 828
832 if (!options) 829 if (!options)
833 return 1; 830 return 1;
834 831
835 if (strncmp(options, "sep=", 4) == 0) { 832 if (strncmp(options, "sep=", 4) == 0) {
836 if (options[4] != 0) { 833 if (options[4] != 0) {
837 separator[0] = options[4]; 834 separator[0] = options[4];
838 options += 5; 835 options += 5;
839 } else { 836 } else {
840 cFYI(1, "Null separator not allowed"); 837 cFYI(1, "Null separator not allowed");
841 } 838 }
842 } 839 }
843 840
844 while ((data = strsep(&options, separator)) != NULL) { 841 while ((data = strsep(&options, separator)) != NULL) {
845 if (!*data) 842 if (!*data)
846 continue; 843 continue;
847 if ((value = strchr(data, '=')) != NULL) 844 if ((value = strchr(data, '=')) != NULL)
848 *value++ = '\0'; 845 *value++ = '\0';
849 846
850 /* Have to parse this before we parse for "user" */ 847 /* Have to parse this before we parse for "user" */
851 if (strnicmp(data, "user_xattr", 10) == 0) { 848 if (strnicmp(data, "user_xattr", 10) == 0) {
852 vol->no_xattr = 0; 849 vol->no_xattr = 0;
853 } else if (strnicmp(data, "nouser_xattr", 12) == 0) { 850 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
854 vol->no_xattr = 1; 851 vol->no_xattr = 1;
855 } else if (strnicmp(data, "user", 4) == 0) { 852 } else if (strnicmp(data, "user", 4) == 0) {
856 if (!value) { 853 if (!value) {
857 printk(KERN_WARNING 854 printk(KERN_WARNING
858 "CIFS: invalid or missing username\n"); 855 "CIFS: invalid or missing username\n");
859 return 1; /* needs_arg; */ 856 return 1; /* needs_arg; */
860 } else if (!*value) { 857 } else if (!*value) {
861 /* null user, ie anonymous, authentication */ 858 /* null user, ie anonymous, authentication */
862 vol->nullauth = 1; 859 vol->nullauth = 1;
863 } 860 }
864 if (strnlen(value, 200) < 200) { 861 if (strnlen(value, 200) < 200) {
865 vol->username = value; 862 vol->username = value;
866 } else { 863 } else {
867 printk(KERN_WARNING "CIFS: username too long\n"); 864 printk(KERN_WARNING "CIFS: username too long\n");
868 return 1; 865 return 1;
869 } 866 }
870 } else if (strnicmp(data, "pass", 4) == 0) { 867 } else if (strnicmp(data, "pass", 4) == 0) {
871 if (!value) { 868 if (!value) {
872 vol->password = NULL; 869 vol->password = NULL;
873 continue; 870 continue;
874 } else if (value[0] == 0) { 871 } else if (value[0] == 0) {
875 /* check if string begins with double comma 872 /* check if string begins with double comma
876 since that would mean the password really 873 since that would mean the password really
877 does start with a comma, and would not 874 does start with a comma, and would not
878 indicate an empty string */ 875 indicate an empty string */
879 if (value[1] != separator[0]) { 876 if (value[1] != separator[0]) {
880 vol->password = NULL; 877 vol->password = NULL;
881 continue; 878 continue;
882 } 879 }
883 } 880 }
884 temp_len = strlen(value); 881 temp_len = strlen(value);
885 /* removed password length check, NTLM passwords 882 /* removed password length check, NTLM passwords
886 can be arbitrarily long */ 883 can be arbitrarily long */
887 884
888 /* if comma in password, the string will be 885 /* if comma in password, the string will be
889 prematurely null terminated. Commas in password are 886 prematurely null terminated. Commas in password are
890 specified across the cifs mount interface by a double 887 specified across the cifs mount interface by a double
891 comma ie ,, and a comma used as in other cases ie ',' 888 comma ie ,, and a comma used as in other cases ie ','
892 as a parameter delimiter/separator is single and due 889 as a parameter delimiter/separator is single and due
893 to the strsep above is temporarily zeroed. */ 890 to the strsep above is temporarily zeroed. */
894 891
895 /* NB: password legally can have multiple commas and 892 /* NB: password legally can have multiple commas and
896 the only illegal character in a password is null */ 893 the only illegal character in a password is null */
897 894
898 if ((value[temp_len] == 0) && 895 if ((value[temp_len] == 0) &&
899 (value[temp_len+1] == separator[0])) { 896 (value[temp_len+1] == separator[0])) {
900 /* reinsert comma */ 897 /* reinsert comma */
901 value[temp_len] = separator[0]; 898 value[temp_len] = separator[0];
902 temp_len += 2; /* move after second comma */ 899 temp_len += 2; /* move after second comma */
903 while (value[temp_len] != 0) { 900 while (value[temp_len] != 0) {
904 if (value[temp_len] == separator[0]) { 901 if (value[temp_len] == separator[0]) {
905 if (value[temp_len+1] == 902 if (value[temp_len+1] ==
906 separator[0]) { 903 separator[0]) {
907 /* skip second comma */ 904 /* skip second comma */
908 temp_len++; 905 temp_len++;
909 } else { 906 } else {
910 /* single comma indicating start 907 /* single comma indicating start
911 of next parm */ 908 of next parm */
912 break; 909 break;
913 } 910 }
914 } 911 }
915 temp_len++; 912 temp_len++;
916 } 913 }
917 if (value[temp_len] == 0) { 914 if (value[temp_len] == 0) {
918 options = NULL; 915 options = NULL;
919 } else { 916 } else {
920 value[temp_len] = 0; 917 value[temp_len] = 0;
921 /* point option to start of next parm */ 918 /* point option to start of next parm */
922 options = value + temp_len + 1; 919 options = value + temp_len + 1;
923 } 920 }
924 /* go from value to value + temp_len condensing 921 /* go from value to value + temp_len condensing
925 double commas to singles. Note that this ends up 922 double commas to singles. Note that this ends up
926 allocating a few bytes too many, which is ok */ 923 allocating a few bytes too many, which is ok */
927 vol->password = kzalloc(temp_len, GFP_KERNEL); 924 vol->password = kzalloc(temp_len, GFP_KERNEL);
928 if (vol->password == NULL) { 925 if (vol->password == NULL) {
929 printk(KERN_WARNING "CIFS: no memory " 926 printk(KERN_WARNING "CIFS: no memory "
930 "for password\n"); 927 "for password\n");
931 return 1; 928 return 1;
932 } 929 }
933 for (i = 0, j = 0; i < temp_len; i++, j++) { 930 for (i = 0, j = 0; i < temp_len; i++, j++) {
934 vol->password[j] = value[i]; 931 vol->password[j] = value[i];
935 if (value[i] == separator[0] 932 if (value[i] == separator[0]
936 && value[i+1] == separator[0]) { 933 && value[i+1] == separator[0]) {
937 /* skip second comma */ 934 /* skip second comma */
938 i++; 935 i++;
939 } 936 }
940 } 937 }
941 vol->password[j] = 0; 938 vol->password[j] = 0;
942 } else { 939 } else {
943 vol->password = kzalloc(temp_len+1, GFP_KERNEL); 940 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
944 if (vol->password == NULL) { 941 if (vol->password == NULL) {
945 printk(KERN_WARNING "CIFS: no memory " 942 printk(KERN_WARNING "CIFS: no memory "
946 "for password\n"); 943 "for password\n");
947 return 1; 944 return 1;
948 } 945 }
949 strcpy(vol->password, value); 946 strcpy(vol->password, value);
950 } 947 }
951 } else if (!strnicmp(data, "ip", 2) || 948 } else if (!strnicmp(data, "ip", 2) ||
952 !strnicmp(data, "addr", 4)) { 949 !strnicmp(data, "addr", 4)) {
953 if (!value || !*value) { 950 if (!value || !*value) {
954 vol->UNCip = NULL; 951 vol->UNCip = NULL;
955 } else if (strnlen(value, INET6_ADDRSTRLEN) < 952 } else if (strnlen(value, INET6_ADDRSTRLEN) <
956 INET6_ADDRSTRLEN) { 953 INET6_ADDRSTRLEN) {
957 vol->UNCip = value; 954 vol->UNCip = value;
958 } else { 955 } else {
959 printk(KERN_WARNING "CIFS: ip address " 956 printk(KERN_WARNING "CIFS: ip address "
960 "too long\n"); 957 "too long\n");
961 return 1; 958 return 1;
962 } 959 }
963 } else if (strnicmp(data, "sec", 3) == 0) { 960 } else if (strnicmp(data, "sec", 3) == 0) {
964 if (!value || !*value) { 961 if (!value || !*value) {
965 cERROR(1, "no security value specified"); 962 cERROR(1, "no security value specified");
966 continue; 963 continue;
967 } else if (strnicmp(value, "krb5i", 5) == 0) { 964 } else if (strnicmp(value, "krb5i", 5) == 0) {
968 vol->secFlg |= CIFSSEC_MAY_KRB5 | 965 vol->secFlg |= CIFSSEC_MAY_KRB5 |
969 CIFSSEC_MUST_SIGN; 966 CIFSSEC_MUST_SIGN;
970 } else if (strnicmp(value, "krb5p", 5) == 0) { 967 } else if (strnicmp(value, "krb5p", 5) == 0) {
971 /* vol->secFlg |= CIFSSEC_MUST_SEAL | 968 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
972 CIFSSEC_MAY_KRB5; */ 969 CIFSSEC_MAY_KRB5; */
973 cERROR(1, "Krb5 cifs privacy not supported"); 970 cERROR(1, "Krb5 cifs privacy not supported");
974 return 1; 971 return 1;
975 } else if (strnicmp(value, "krb5", 4) == 0) { 972 } else if (strnicmp(value, "krb5", 4) == 0) {
976 vol->secFlg |= CIFSSEC_MAY_KRB5; 973 vol->secFlg |= CIFSSEC_MAY_KRB5;
977 } else if (strnicmp(value, "ntlmsspi", 8) == 0) { 974 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
978 vol->secFlg |= CIFSSEC_MAY_NTLMSSP | 975 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
979 CIFSSEC_MUST_SIGN; 976 CIFSSEC_MUST_SIGN;
980 } else if (strnicmp(value, "ntlmssp", 7) == 0) { 977 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
981 vol->secFlg |= CIFSSEC_MAY_NTLMSSP; 978 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
982 } else if (strnicmp(value, "ntlmv2i", 7) == 0) { 979 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
983 vol->secFlg |= CIFSSEC_MAY_NTLMV2 | 980 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
984 CIFSSEC_MUST_SIGN; 981 CIFSSEC_MUST_SIGN;
985 } else if (strnicmp(value, "ntlmv2", 6) == 0) { 982 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
986 vol->secFlg |= CIFSSEC_MAY_NTLMV2; 983 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
987 } else if (strnicmp(value, "ntlmi", 5) == 0) { 984 } else if (strnicmp(value, "ntlmi", 5) == 0) {
988 vol->secFlg |= CIFSSEC_MAY_NTLM | 985 vol->secFlg |= CIFSSEC_MAY_NTLM |
989 CIFSSEC_MUST_SIGN; 986 CIFSSEC_MUST_SIGN;
990 } else if (strnicmp(value, "ntlm", 4) == 0) { 987 } else if (strnicmp(value, "ntlm", 4) == 0) {
991 /* ntlm is default so can be turned off too */ 988 /* ntlm is default so can be turned off too */
992 vol->secFlg |= CIFSSEC_MAY_NTLM; 989 vol->secFlg |= CIFSSEC_MAY_NTLM;
993 } else if (strnicmp(value, "nontlm", 6) == 0) { 990 } else if (strnicmp(value, "nontlm", 6) == 0) {
994 /* BB is there a better way to do this? */ 991 /* BB is there a better way to do this? */
995 vol->secFlg |= CIFSSEC_MAY_NTLMV2; 992 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
996 #ifdef CONFIG_CIFS_WEAK_PW_HASH 993 #ifdef CONFIG_CIFS_WEAK_PW_HASH
997 } else if (strnicmp(value, "lanman", 6) == 0) { 994 } else if (strnicmp(value, "lanman", 6) == 0) {
998 vol->secFlg |= CIFSSEC_MAY_LANMAN; 995 vol->secFlg |= CIFSSEC_MAY_LANMAN;
999 #endif 996 #endif
1000 } else if (strnicmp(value, "none", 4) == 0) { 997 } else if (strnicmp(value, "none", 4) == 0) {
1001 vol->nullauth = 1; 998 vol->nullauth = 1;
1002 } else { 999 } else {
1003 cERROR(1, "bad security option: %s", value); 1000 cERROR(1, "bad security option: %s", value);
1004 return 1; 1001 return 1;
1005 } 1002 }
1006 } else if ((strnicmp(data, "unc", 3) == 0) 1003 } else if ((strnicmp(data, "unc", 3) == 0)
1007 || (strnicmp(data, "target", 6) == 0) 1004 || (strnicmp(data, "target", 6) == 0)
1008 || (strnicmp(data, "path", 4) == 0)) { 1005 || (strnicmp(data, "path", 4) == 0)) {
1009 if (!value || !*value) { 1006 if (!value || !*value) {
1010 printk(KERN_WARNING "CIFS: invalid path to " 1007 printk(KERN_WARNING "CIFS: invalid path to "
1011 "network resource\n"); 1008 "network resource\n");
1012 return 1; /* needs_arg; */ 1009 return 1; /* needs_arg; */
1013 } 1010 }
1014 if ((temp_len = strnlen(value, 300)) < 300) { 1011 if ((temp_len = strnlen(value, 300)) < 300) {
1015 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); 1012 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1016 if (vol->UNC == NULL) 1013 if (vol->UNC == NULL)
1017 return 1; 1014 return 1;
1018 strcpy(vol->UNC, value); 1015 strcpy(vol->UNC, value);
1019 if (strncmp(vol->UNC, "//", 2) == 0) { 1016 if (strncmp(vol->UNC, "//", 2) == 0) {
1020 vol->UNC[0] = '\\'; 1017 vol->UNC[0] = '\\';
1021 vol->UNC[1] = '\\'; 1018 vol->UNC[1] = '\\';
1022 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { 1019 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1023 printk(KERN_WARNING 1020 printk(KERN_WARNING
1024 "CIFS: UNC Path does not begin " 1021 "CIFS: UNC Path does not begin "
1025 "with // or \\\\ \n"); 1022 "with // or \\\\ \n");
1026 return 1; 1023 return 1;
1027 } 1024 }
1028 } else { 1025 } else {
1029 printk(KERN_WARNING "CIFS: UNC name too long\n"); 1026 printk(KERN_WARNING "CIFS: UNC name too long\n");
1030 return 1; 1027 return 1;
1031 } 1028 }
1032 } else if ((strnicmp(data, "domain", 3) == 0) 1029 } else if ((strnicmp(data, "domain", 3) == 0)
1033 || (strnicmp(data, "workgroup", 5) == 0)) { 1030 || (strnicmp(data, "workgroup", 5) == 0)) {
1034 if (!value || !*value) { 1031 if (!value || !*value) {
1035 printk(KERN_WARNING "CIFS: invalid domain name\n"); 1032 printk(KERN_WARNING "CIFS: invalid domain name\n");
1036 return 1; /* needs_arg; */ 1033 return 1; /* needs_arg; */
1037 } 1034 }
1038 /* BB are there cases in which a comma can be valid in 1035 /* BB are there cases in which a comma can be valid in
1039 a domain name and need special handling? */ 1036 a domain name and need special handling? */
1040 if (strnlen(value, 256) < 256) { 1037 if (strnlen(value, 256) < 256) {
1041 vol->domainname = value; 1038 vol->domainname = value;
1042 cFYI(1, "Domain name set"); 1039 cFYI(1, "Domain name set");
1043 } else { 1040 } else {
1044 printk(KERN_WARNING "CIFS: domain name too " 1041 printk(KERN_WARNING "CIFS: domain name too "
1045 "long\n"); 1042 "long\n");
1046 return 1; 1043 return 1;
1047 } 1044 }
1048 } else if (strnicmp(data, "srcaddr", 7) == 0) { 1045 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1049 vol->srcaddr.ss_family = AF_UNSPEC; 1046 vol->srcaddr.ss_family = AF_UNSPEC;
1050 1047
1051 if (!value || !*value) { 1048 if (!value || !*value) {
1052 printk(KERN_WARNING "CIFS: srcaddr value" 1049 printk(KERN_WARNING "CIFS: srcaddr value"
1053 " not specified.\n"); 1050 " not specified.\n");
1054 return 1; /* needs_arg; */ 1051 return 1; /* needs_arg; */
1055 } 1052 }
1056 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr, 1053 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1057 value, strlen(value)); 1054 value, strlen(value));
1058 if (i == 0) { 1055 if (i == 0) {
1059 printk(KERN_WARNING "CIFS: Could not parse" 1056 printk(KERN_WARNING "CIFS: Could not parse"
1060 " srcaddr: %s\n", 1057 " srcaddr: %s\n",
1061 value); 1058 value);
1062 return 1; 1059 return 1;
1063 } 1060 }
1064 } else if (strnicmp(data, "prefixpath", 10) == 0) { 1061 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1065 if (!value || !*value) { 1062 if (!value || !*value) {
1066 printk(KERN_WARNING 1063 printk(KERN_WARNING
1067 "CIFS: invalid path prefix\n"); 1064 "CIFS: invalid path prefix\n");
1068 return 1; /* needs_argument */ 1065 return 1; /* needs_argument */
1069 } 1066 }
1070 if ((temp_len = strnlen(value, 1024)) < 1024) { 1067 if ((temp_len = strnlen(value, 1024)) < 1024) {
1071 if (value[0] != '/') 1068 if (value[0] != '/')
1072 temp_len++; /* missing leading slash */ 1069 temp_len++; /* missing leading slash */
1073 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL); 1070 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1074 if (vol->prepath == NULL) 1071 if (vol->prepath == NULL)
1075 return 1; 1072 return 1;
1076 if (value[0] != '/') { 1073 if (value[0] != '/') {
1077 vol->prepath[0] = '/'; 1074 vol->prepath[0] = '/';
1078 strcpy(vol->prepath+1, value); 1075 strcpy(vol->prepath+1, value);
1079 } else 1076 } else
1080 strcpy(vol->prepath, value); 1077 strcpy(vol->prepath, value);
1081 cFYI(1, "prefix path %s", vol->prepath); 1078 cFYI(1, "prefix path %s", vol->prepath);
1082 } else { 1079 } else {
1083 printk(KERN_WARNING "CIFS: prefix too long\n"); 1080 printk(KERN_WARNING "CIFS: prefix too long\n");
1084 return 1; 1081 return 1;
1085 } 1082 }
1086 } else if (strnicmp(data, "iocharset", 9) == 0) { 1083 } else if (strnicmp(data, "iocharset", 9) == 0) {
1087 if (!value || !*value) { 1084 if (!value || !*value) {
1088 printk(KERN_WARNING "CIFS: invalid iocharset " 1085 printk(KERN_WARNING "CIFS: invalid iocharset "
1089 "specified\n"); 1086 "specified\n");
1090 return 1; /* needs_arg; */ 1087 return 1; /* needs_arg; */
1091 } 1088 }
1092 if (strnlen(value, 65) < 65) { 1089 if (strnlen(value, 65) < 65) {
1093 if (strnicmp(value, "default", 7)) 1090 if (strnicmp(value, "default", 7))
1094 vol->iocharset = value; 1091 vol->iocharset = value;
1095 /* if iocharset not set then load_nls_default 1092 /* if iocharset not set then load_nls_default
1096 is used by caller */ 1093 is used by caller */
1097 cFYI(1, "iocharset set to %s", value); 1094 cFYI(1, "iocharset set to %s", value);
1098 } else { 1095 } else {
1099 printk(KERN_WARNING "CIFS: iocharset name " 1096 printk(KERN_WARNING "CIFS: iocharset name "
1100 "too long.\n"); 1097 "too long.\n");
1101 return 1; 1098 return 1;
1102 } 1099 }
1103 } else if (!strnicmp(data, "uid", 3) && value && *value) { 1100 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1104 vol->linux_uid = simple_strtoul(value, &value, 0); 1101 vol->linux_uid = simple_strtoul(value, &value, 0);
1105 uid_specified = true; 1102 uid_specified = true;
1106 } else if (!strnicmp(data, "cruid", 5) && value && *value) { 1103 } else if (!strnicmp(data, "cruid", 5) && value && *value) {
1107 vol->cred_uid = simple_strtoul(value, &value, 0); 1104 vol->cred_uid = simple_strtoul(value, &value, 0);
1108 } else if (!strnicmp(data, "forceuid", 8)) { 1105 } else if (!strnicmp(data, "forceuid", 8)) {
1109 override_uid = 1; 1106 override_uid = 1;
1110 } else if (!strnicmp(data, "noforceuid", 10)) { 1107 } else if (!strnicmp(data, "noforceuid", 10)) {
1111 override_uid = 0; 1108 override_uid = 0;
1112 } else if (!strnicmp(data, "gid", 3) && value && *value) { 1109 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1113 vol->linux_gid = simple_strtoul(value, &value, 0); 1110 vol->linux_gid = simple_strtoul(value, &value, 0);
1114 gid_specified = true; 1111 gid_specified = true;
1115 } else if (!strnicmp(data, "forcegid", 8)) { 1112 } else if (!strnicmp(data, "forcegid", 8)) {
1116 override_gid = 1; 1113 override_gid = 1;
1117 } else if (!strnicmp(data, "noforcegid", 10)) { 1114 } else if (!strnicmp(data, "noforcegid", 10)) {
1118 override_gid = 0; 1115 override_gid = 0;
1119 } else if (strnicmp(data, "file_mode", 4) == 0) { 1116 } else if (strnicmp(data, "file_mode", 4) == 0) {
1120 if (value && *value) { 1117 if (value && *value) {
1121 vol->file_mode = 1118 vol->file_mode =
1122 simple_strtoul(value, &value, 0); 1119 simple_strtoul(value, &value, 0);
1123 } 1120 }
1124 } else if (strnicmp(data, "dir_mode", 4) == 0) { 1121 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1125 if (value && *value) { 1122 if (value && *value) {
1126 vol->dir_mode = 1123 vol->dir_mode =
1127 simple_strtoul(value, &value, 0); 1124 simple_strtoul(value, &value, 0);
1128 } 1125 }
1129 } else if (strnicmp(data, "dirmode", 4) == 0) { 1126 } else if (strnicmp(data, "dirmode", 4) == 0) {
1130 if (value && *value) { 1127 if (value && *value) {
1131 vol->dir_mode = 1128 vol->dir_mode =
1132 simple_strtoul(value, &value, 0); 1129 simple_strtoul(value, &value, 0);
1133 } 1130 }
1134 } else if (strnicmp(data, "port", 4) == 0) { 1131 } else if (strnicmp(data, "port", 4) == 0) {
1135 if (value && *value) { 1132 if (value && *value) {
1136 vol->port = 1133 vol->port =
1137 simple_strtoul(value, &value, 0); 1134 simple_strtoul(value, &value, 0);
1138 } 1135 }
1139 } else if (strnicmp(data, "rsize", 5) == 0) { 1136 } else if (strnicmp(data, "rsize", 5) == 0) {
1140 if (value && *value) { 1137 if (value && *value) {
1141 vol->rsize = 1138 vol->rsize =
1142 simple_strtoul(value, &value, 0); 1139 simple_strtoul(value, &value, 0);
1143 } 1140 }
1144 } else if (strnicmp(data, "wsize", 5) == 0) { 1141 } else if (strnicmp(data, "wsize", 5) == 0) {
1145 if (value && *value) { 1142 if (value && *value) {
1146 vol->wsize = 1143 vol->wsize =
1147 simple_strtoul(value, &value, 0); 1144 simple_strtoul(value, &value, 0);
1148 } 1145 }
1149 } else if (strnicmp(data, "sockopt", 5) == 0) { 1146 } else if (strnicmp(data, "sockopt", 5) == 0) {
1150 if (!value || !*value) { 1147 if (!value || !*value) {
1151 cERROR(1, "no socket option specified"); 1148 cERROR(1, "no socket option specified");
1152 continue; 1149 continue;
1153 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) { 1150 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1154 vol->sockopt_tcp_nodelay = 1; 1151 vol->sockopt_tcp_nodelay = 1;
1155 } 1152 }
1156 } else if (strnicmp(data, "netbiosname", 4) == 0) { 1153 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1157 if (!value || !*value || (*value == ' ')) { 1154 if (!value || !*value || (*value == ' ')) {
1158 cFYI(1, "invalid (empty) netbiosname"); 1155 cFYI(1, "invalid (empty) netbiosname");
1159 } else { 1156 } else {
1160 memset(vol->source_rfc1001_name, 0x20, 1157 memset(vol->source_rfc1001_name, 0x20,
1161 RFC1001_NAME_LEN); 1158 RFC1001_NAME_LEN);
1162 /* 1159 /*
1163 * FIXME: are there cases in which a comma can 1160 * FIXME: are there cases in which a comma can
1164 * be valid in workstation netbios name (and 1161 * be valid in workstation netbios name (and
1165 * need special handling)? 1162 * need special handling)?
1166 */ 1163 */
1167 for (i = 0; i < RFC1001_NAME_LEN; i++) { 1164 for (i = 0; i < RFC1001_NAME_LEN; i++) {
1168 /* don't ucase netbiosname for user */ 1165 /* don't ucase netbiosname for user */
1169 if (value[i] == 0) 1166 if (value[i] == 0)
1170 break; 1167 break;
1171 vol->source_rfc1001_name[i] = value[i]; 1168 vol->source_rfc1001_name[i] = value[i];
1172 } 1169 }
1173 /* The string has 16th byte zero still from 1170 /* The string has 16th byte zero still from
1174 set at top of the function */ 1171 set at top of the function */
1175 if (i == RFC1001_NAME_LEN && value[i] != 0) 1172 if (i == RFC1001_NAME_LEN && value[i] != 0)
1176 printk(KERN_WARNING "CIFS: netbiosname" 1173 printk(KERN_WARNING "CIFS: netbiosname"
1177 " longer than 15 truncated.\n"); 1174 " longer than 15 truncated.\n");
1178 } 1175 }
1179 } else if (strnicmp(data, "servern", 7) == 0) { 1176 } else if (strnicmp(data, "servern", 7) == 0) {
1180 /* servernetbiosname specified override *SMBSERVER */ 1177 /* servernetbiosname specified override *SMBSERVER */
1181 if (!value || !*value || (*value == ' ')) { 1178 if (!value || !*value || (*value == ' ')) {
1182 cFYI(1, "empty server netbiosname specified"); 1179 cFYI(1, "empty server netbiosname specified");
1183 } else { 1180 } else {
1184 /* last byte, type, is 0x20 for servr type */ 1181 /* last byte, type, is 0x20 for servr type */
1185 memset(vol->target_rfc1001_name, 0x20, 1182 memset(vol->target_rfc1001_name, 0x20,
1186 RFC1001_NAME_LEN_WITH_NULL); 1183 RFC1001_NAME_LEN_WITH_NULL);
1187 1184
1188 for (i = 0; i < 15; i++) { 1185 for (i = 0; i < 15; i++) {
1189 /* BB are there cases in which a comma can be 1186 /* BB are there cases in which a comma can be
1190 valid in this workstation netbios name 1187 valid in this workstation netbios name
1191 (and need special handling)? */ 1188 (and need special handling)? */
1192 1189
1193 /* user or mount helper must uppercase 1190 /* user or mount helper must uppercase
1194 the netbiosname */ 1191 the netbiosname */
1195 if (value[i] == 0) 1192 if (value[i] == 0)
1196 break; 1193 break;
1197 else 1194 else
1198 vol->target_rfc1001_name[i] = 1195 vol->target_rfc1001_name[i] =
1199 value[i]; 1196 value[i];
1200 } 1197 }
1201 /* The string has 16th byte zero still from 1198 /* The string has 16th byte zero still from
1202 set at top of the function */ 1199 set at top of the function */
1203 if (i == RFC1001_NAME_LEN && value[i] != 0) 1200 if (i == RFC1001_NAME_LEN && value[i] != 0)
1204 printk(KERN_WARNING "CIFS: server net" 1201 printk(KERN_WARNING "CIFS: server net"
1205 "biosname longer than 15 truncated.\n"); 1202 "biosname longer than 15 truncated.\n");
1206 } 1203 }
1207 } else if (strnicmp(data, "actimeo", 7) == 0) { 1204 } else if (strnicmp(data, "actimeo", 7) == 0) {
1208 if (value && *value) { 1205 if (value && *value) {
1209 vol->actimeo = HZ * simple_strtoul(value, 1206 vol->actimeo = HZ * simple_strtoul(value,
1210 &value, 0); 1207 &value, 0);
1211 if (vol->actimeo > CIFS_MAX_ACTIMEO) { 1208 if (vol->actimeo > CIFS_MAX_ACTIMEO) {
1212 cERROR(1, "CIFS: attribute cache" 1209 cERROR(1, "CIFS: attribute cache"
1213 "timeout too large"); 1210 "timeout too large");
1214 return 1; 1211 return 1;
1215 } 1212 }
1216 } 1213 }
1217 } else if (strnicmp(data, "credentials", 4) == 0) { 1214 } else if (strnicmp(data, "credentials", 4) == 0) {
1218 /* ignore */ 1215 /* ignore */
1219 } else if (strnicmp(data, "version", 3) == 0) { 1216 } else if (strnicmp(data, "version", 3) == 0) {
1220 /* ignore */ 1217 /* ignore */
1221 } else if (strnicmp(data, "guest", 5) == 0) { 1218 } else if (strnicmp(data, "guest", 5) == 0) {
1222 /* ignore */ 1219 /* ignore */
1223 } else if (strnicmp(data, "rw", 2) == 0) { 1220 } else if (strnicmp(data, "rw", 2) == 0) {
1224 /* ignore */ 1221 /* ignore */
1225 } else if (strnicmp(data, "ro", 2) == 0) { 1222 } else if (strnicmp(data, "ro", 2) == 0) {
1226 /* ignore */ 1223 /* ignore */
1227 } else if (strnicmp(data, "noblocksend", 11) == 0) { 1224 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1228 vol->noblocksnd = 1; 1225 vol->noblocksnd = 1;
1229 } else if (strnicmp(data, "noautotune", 10) == 0) { 1226 } else if (strnicmp(data, "noautotune", 10) == 0) {
1230 vol->noautotune = 1; 1227 vol->noautotune = 1;
1231 } else if ((strnicmp(data, "suid", 4) == 0) || 1228 } else if ((strnicmp(data, "suid", 4) == 0) ||
1232 (strnicmp(data, "nosuid", 6) == 0) || 1229 (strnicmp(data, "nosuid", 6) == 0) ||
1233 (strnicmp(data, "exec", 4) == 0) || 1230 (strnicmp(data, "exec", 4) == 0) ||
1234 (strnicmp(data, "noexec", 6) == 0) || 1231 (strnicmp(data, "noexec", 6) == 0) ||
1235 (strnicmp(data, "nodev", 5) == 0) || 1232 (strnicmp(data, "nodev", 5) == 0) ||
1236 (strnicmp(data, "noauto", 6) == 0) || 1233 (strnicmp(data, "noauto", 6) == 0) ||
1237 (strnicmp(data, "dev", 3) == 0)) { 1234 (strnicmp(data, "dev", 3) == 0)) {
1238 /* The mount tool or mount.cifs helper (if present) 1235 /* The mount tool or mount.cifs helper (if present)
1239 uses these opts to set flags, and the flags are read 1236 uses these opts to set flags, and the flags are read
1240 by the kernel vfs layer before we get here (ie 1237 by the kernel vfs layer before we get here (ie
1241 before read super) so there is no point trying to 1238 before read super) so there is no point trying to
1242 parse these options again and set anything and it 1239 parse these options again and set anything and it
1243 is ok to just ignore them */ 1240 is ok to just ignore them */
1244 continue; 1241 continue;
1245 } else if (strnicmp(data, "hard", 4) == 0) { 1242 } else if (strnicmp(data, "hard", 4) == 0) {
1246 vol->retry = 1; 1243 vol->retry = 1;
1247 } else if (strnicmp(data, "soft", 4) == 0) { 1244 } else if (strnicmp(data, "soft", 4) == 0) {
1248 vol->retry = 0; 1245 vol->retry = 0;
1249 } else if (strnicmp(data, "perm", 4) == 0) { 1246 } else if (strnicmp(data, "perm", 4) == 0) {
1250 vol->noperm = 0; 1247 vol->noperm = 0;
1251 } else if (strnicmp(data, "noperm", 6) == 0) { 1248 } else if (strnicmp(data, "noperm", 6) == 0) {
1252 vol->noperm = 1; 1249 vol->noperm = 1;
1253 } else if (strnicmp(data, "mapchars", 8) == 0) { 1250 } else if (strnicmp(data, "mapchars", 8) == 0) {
1254 vol->remap = 1; 1251 vol->remap = 1;
1255 } else if (strnicmp(data, "nomapchars", 10) == 0) { 1252 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1256 vol->remap = 0; 1253 vol->remap = 0;
1257 } else if (strnicmp(data, "sfu", 3) == 0) { 1254 } else if (strnicmp(data, "sfu", 3) == 0) {
1258 vol->sfu_emul = 1; 1255 vol->sfu_emul = 1;
1259 } else if (strnicmp(data, "nosfu", 5) == 0) { 1256 } else if (strnicmp(data, "nosfu", 5) == 0) {
1260 vol->sfu_emul = 0; 1257 vol->sfu_emul = 0;
1261 } else if (strnicmp(data, "nodfs", 5) == 0) { 1258 } else if (strnicmp(data, "nodfs", 5) == 0) {
1262 vol->nodfs = 1; 1259 vol->nodfs = 1;
1263 } else if (strnicmp(data, "posixpaths", 10) == 0) { 1260 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1264 vol->posix_paths = 1; 1261 vol->posix_paths = 1;
1265 } else if (strnicmp(data, "noposixpaths", 12) == 0) { 1262 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1266 vol->posix_paths = 0; 1263 vol->posix_paths = 0;
1267 } else if (strnicmp(data, "nounix", 6) == 0) { 1264 } else if (strnicmp(data, "nounix", 6) == 0) {
1268 vol->no_linux_ext = 1; 1265 vol->no_linux_ext = 1;
1269 } else if (strnicmp(data, "nolinux", 7) == 0) { 1266 } else if (strnicmp(data, "nolinux", 7) == 0) {
1270 vol->no_linux_ext = 1; 1267 vol->no_linux_ext = 1;
1271 } else if ((strnicmp(data, "nocase", 6) == 0) || 1268 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1272 (strnicmp(data, "ignorecase", 10) == 0)) { 1269 (strnicmp(data, "ignorecase", 10) == 0)) {
1273 vol->nocase = 1; 1270 vol->nocase = 1;
1274 } else if (strnicmp(data, "mand", 4) == 0) { 1271 } else if (strnicmp(data, "mand", 4) == 0) {
1275 /* ignore */ 1272 /* ignore */
1276 } else if (strnicmp(data, "nomand", 6) == 0) { 1273 } else if (strnicmp(data, "nomand", 6) == 0) {
1277 /* ignore */ 1274 /* ignore */
1278 } else if (strnicmp(data, "_netdev", 7) == 0) { 1275 } else if (strnicmp(data, "_netdev", 7) == 0) {
1279 /* ignore */ 1276 /* ignore */
1280 } else if (strnicmp(data, "brl", 3) == 0) { 1277 } else if (strnicmp(data, "brl", 3) == 0) {
1281 vol->nobrl = 0; 1278 vol->nobrl = 0;
1282 } else if ((strnicmp(data, "nobrl", 5) == 0) || 1279 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1283 (strnicmp(data, "nolock", 6) == 0)) { 1280 (strnicmp(data, "nolock", 6) == 0)) {
1284 vol->nobrl = 1; 1281 vol->nobrl = 1;
1285 /* turn off mandatory locking in mode 1282 /* turn off mandatory locking in mode
1286 if remote locking is turned off since the 1283 if remote locking is turned off since the
1287 local vfs will do advisory */ 1284 local vfs will do advisory */
1288 if (vol->file_mode == 1285 if (vol->file_mode ==
1289 (S_IALLUGO & ~(S_ISUID | S_IXGRP))) 1286 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1290 vol->file_mode = S_IALLUGO; 1287 vol->file_mode = S_IALLUGO;
1291 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) { 1288 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1292 /* will take the shorter form "forcemand" as well */ 1289 /* will take the shorter form "forcemand" as well */
1293 /* This mount option will force use of mandatory 1290 /* This mount option will force use of mandatory
1294 (DOS/Windows style) byte range locks, instead of 1291 (DOS/Windows style) byte range locks, instead of
1295 using posix advisory byte range locks, even if the 1292 using posix advisory byte range locks, even if the
1296 Unix extensions are available and posix locks would 1293 Unix extensions are available and posix locks would
1297 be supported otherwise. If Unix extensions are not 1294 be supported otherwise. If Unix extensions are not
1298 negotiated this has no effect since mandatory locks 1295 negotiated this has no effect since mandatory locks
1299 would be used (mandatory locks is all that those 1296 would be used (mandatory locks is all that those
1300 those servers support) */ 1297 those servers support) */
1301 vol->mand_lock = 1; 1298 vol->mand_lock = 1;
1302 } else if (strnicmp(data, "setuids", 7) == 0) { 1299 } else if (strnicmp(data, "setuids", 7) == 0) {
1303 vol->setuids = 1; 1300 vol->setuids = 1;
1304 } else if (strnicmp(data, "nosetuids", 9) == 0) { 1301 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1305 vol->setuids = 0; 1302 vol->setuids = 0;
1306 } else if (strnicmp(data, "dynperm", 7) == 0) { 1303 } else if (strnicmp(data, "dynperm", 7) == 0) {
1307 vol->dynperm = true; 1304 vol->dynperm = true;
1308 } else if (strnicmp(data, "nodynperm", 9) == 0) { 1305 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1309 vol->dynperm = false; 1306 vol->dynperm = false;
1310 } else if (strnicmp(data, "nohard", 6) == 0) { 1307 } else if (strnicmp(data, "nohard", 6) == 0) {
1311 vol->retry = 0; 1308 vol->retry = 0;
1312 } else if (strnicmp(data, "nosoft", 6) == 0) { 1309 } else if (strnicmp(data, "nosoft", 6) == 0) {
1313 vol->retry = 1; 1310 vol->retry = 1;
1314 } else if (strnicmp(data, "nointr", 6) == 0) { 1311 } else if (strnicmp(data, "nointr", 6) == 0) {
1315 vol->intr = 0; 1312 vol->intr = 0;
1316 } else if (strnicmp(data, "intr", 4) == 0) { 1313 } else if (strnicmp(data, "intr", 4) == 0) {
1317 vol->intr = 1; 1314 vol->intr = 1;
1318 } else if (strnicmp(data, "nostrictsync", 12) == 0) { 1315 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1319 vol->nostrictsync = 1; 1316 vol->nostrictsync = 1;
1320 } else if (strnicmp(data, "strictsync", 10) == 0) { 1317 } else if (strnicmp(data, "strictsync", 10) == 0) {
1321 vol->nostrictsync = 0; 1318 vol->nostrictsync = 0;
1322 } else if (strnicmp(data, "serverino", 7) == 0) { 1319 } else if (strnicmp(data, "serverino", 7) == 0) {
1323 vol->server_ino = 1; 1320 vol->server_ino = 1;
1324 } else if (strnicmp(data, "noserverino", 9) == 0) { 1321 } else if (strnicmp(data, "noserverino", 9) == 0) {
1325 vol->server_ino = 0; 1322 vol->server_ino = 0;
1326 } else if (strnicmp(data, "cifsacl", 7) == 0) { 1323 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1327 vol->cifs_acl = 1; 1324 vol->cifs_acl = 1;
1328 } else if (strnicmp(data, "nocifsacl", 9) == 0) { 1325 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1329 vol->cifs_acl = 0; 1326 vol->cifs_acl = 0;
1330 } else if (strnicmp(data, "acl", 3) == 0) { 1327 } else if (strnicmp(data, "acl", 3) == 0) {
1331 vol->no_psx_acl = 0; 1328 vol->no_psx_acl = 0;
1332 } else if (strnicmp(data, "noacl", 5) == 0) { 1329 } else if (strnicmp(data, "noacl", 5) == 0) {
1333 vol->no_psx_acl = 1; 1330 vol->no_psx_acl = 1;
1334 } else if (strnicmp(data, "locallease", 6) == 0) { 1331 } else if (strnicmp(data, "locallease", 6) == 0) {
1335 vol->local_lease = 1; 1332 vol->local_lease = 1;
1336 } else if (strnicmp(data, "sign", 4) == 0) { 1333 } else if (strnicmp(data, "sign", 4) == 0) {
1337 vol->secFlg |= CIFSSEC_MUST_SIGN; 1334 vol->secFlg |= CIFSSEC_MUST_SIGN;
1338 } else if (strnicmp(data, "seal", 4) == 0) { 1335 } else if (strnicmp(data, "seal", 4) == 0) {
1339 /* we do not do the following in secFlags because seal 1336 /* we do not do the following in secFlags because seal
1340 is a per tree connection (mount) not a per socket 1337 is a per tree connection (mount) not a per socket
1341 or per-smb connection option in the protocol */ 1338 or per-smb connection option in the protocol */
1342 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */ 1339 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1343 vol->seal = 1; 1340 vol->seal = 1;
1344 } else if (strnicmp(data, "direct", 6) == 0) { 1341 } else if (strnicmp(data, "direct", 6) == 0) {
1345 vol->direct_io = 1; 1342 vol->direct_io = 1;
1346 } else if (strnicmp(data, "forcedirectio", 13) == 0) { 1343 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1347 vol->direct_io = 1; 1344 vol->direct_io = 1;
1348 } else if (strnicmp(data, "strictcache", 11) == 0) { 1345 } else if (strnicmp(data, "strictcache", 11) == 0) {
1349 vol->strict_io = 1; 1346 vol->strict_io = 1;
1350 } else if (strnicmp(data, "noac", 4) == 0) { 1347 } else if (strnicmp(data, "noac", 4) == 0) {
1351 printk(KERN_WARNING "CIFS: Mount option noac not " 1348 printk(KERN_WARNING "CIFS: Mount option noac not "
1352 "supported. Instead set " 1349 "supported. Instead set "
1353 "/proc/fs/cifs/LookupCacheEnabled to 0\n"); 1350 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1354 } else if (strnicmp(data, "fsc", 3) == 0) { 1351 } else if (strnicmp(data, "fsc", 3) == 0) {
1355 #ifndef CONFIG_CIFS_FSCACHE 1352 #ifndef CONFIG_CIFS_FSCACHE
1356 cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE" 1353 cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
1357 "kernel config option set"); 1354 "kernel config option set");
1358 return 1; 1355 return 1;
1359 #endif 1356 #endif
1360 vol->fsc = true; 1357 vol->fsc = true;
1361 } else if (strnicmp(data, "mfsymlinks", 10) == 0) { 1358 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1362 vol->mfsymlinks = true; 1359 vol->mfsymlinks = true;
1363 } else if (strnicmp(data, "multiuser", 8) == 0) { 1360 } else if (strnicmp(data, "multiuser", 8) == 0) {
1364 vol->multiuser = true; 1361 vol->multiuser = true;
1365 } else 1362 } else
1366 printk(KERN_WARNING "CIFS: Unknown mount option %s\n", 1363 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1367 data); 1364 data);
1368 } 1365 }
1369 if (vol->UNC == NULL) { 1366 if (vol->UNC == NULL) {
1370 if (devname == NULL) { 1367 if (devname == NULL) {
1371 printk(KERN_WARNING "CIFS: Missing UNC name for mount " 1368 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1372 "target\n"); 1369 "target\n");
1373 return 1; 1370 return 1;
1374 } 1371 }
1375 if ((temp_len = strnlen(devname, 300)) < 300) { 1372 if ((temp_len = strnlen(devname, 300)) < 300) {
1376 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); 1373 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1377 if (vol->UNC == NULL) 1374 if (vol->UNC == NULL)
1378 return 1; 1375 return 1;
1379 strcpy(vol->UNC, devname); 1376 strcpy(vol->UNC, devname);
1380 if (strncmp(vol->UNC, "//", 2) == 0) { 1377 if (strncmp(vol->UNC, "//", 2) == 0) {
1381 vol->UNC[0] = '\\'; 1378 vol->UNC[0] = '\\';
1382 vol->UNC[1] = '\\'; 1379 vol->UNC[1] = '\\';
1383 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { 1380 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1384 printk(KERN_WARNING "CIFS: UNC Path does not " 1381 printk(KERN_WARNING "CIFS: UNC Path does not "
1385 "begin with // or \\\\ \n"); 1382 "begin with // or \\\\ \n");
1386 return 1; 1383 return 1;
1387 } 1384 }
1388 value = strpbrk(vol->UNC+2, "/\\"); 1385 value = strpbrk(vol->UNC+2, "/\\");
1389 if (value) 1386 if (value)
1390 *value = '\\'; 1387 *value = '\\';
1391 } else { 1388 } else {
1392 printk(KERN_WARNING "CIFS: UNC name too long\n"); 1389 printk(KERN_WARNING "CIFS: UNC name too long\n");
1393 return 1; 1390 return 1;
1394 } 1391 }
1395 } 1392 }
1396 1393
1397 if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) { 1394 if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) {
1398 cERROR(1, "Multiuser mounts currently require krb5 " 1395 cERROR(1, "Multiuser mounts currently require krb5 "
1399 "authentication!"); 1396 "authentication!");
1400 return 1; 1397 return 1;
1401 } 1398 }
1402 1399
1403 if (vol->UNCip == NULL) 1400 if (vol->UNCip == NULL)
1404 vol->UNCip = &vol->UNC[2]; 1401 vol->UNCip = &vol->UNC[2];
1405 1402
1406 if (uid_specified) 1403 if (uid_specified)
1407 vol->override_uid = override_uid; 1404 vol->override_uid = override_uid;
1408 else if (override_uid == 1) 1405 else if (override_uid == 1)
1409 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option " 1406 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1410 "specified with no uid= option.\n"); 1407 "specified with no uid= option.\n");
1411 1408
1412 if (gid_specified) 1409 if (gid_specified)
1413 vol->override_gid = override_gid; 1410 vol->override_gid = override_gid;
1414 else if (override_gid == 1) 1411 else if (override_gid == 1)
1415 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option " 1412 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1416 "specified with no gid= option.\n"); 1413 "specified with no gid= option.\n");
1417 1414
1418 return 0; 1415 return 0;
1419 } 1416 }
1420 1417
1421 /** Returns true if srcaddr isn't specified and rhs isn't 1418 /** Returns true if srcaddr isn't specified and rhs isn't
1422 * specified, or if srcaddr is specified and 1419 * specified, or if srcaddr is specified and
1423 * matches the IP address of the rhs argument. 1420 * matches the IP address of the rhs argument.
1424 */ 1421 */
1425 static bool 1422 static bool
1426 srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs) 1423 srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1427 { 1424 {
1428 switch (srcaddr->sa_family) { 1425 switch (srcaddr->sa_family) {
1429 case AF_UNSPEC: 1426 case AF_UNSPEC:
1430 return (rhs->sa_family == AF_UNSPEC); 1427 return (rhs->sa_family == AF_UNSPEC);
1431 case AF_INET: { 1428 case AF_INET: {
1432 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr; 1429 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1433 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs; 1430 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1434 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr); 1431 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1435 } 1432 }
1436 case AF_INET6: { 1433 case AF_INET6: {
1437 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr; 1434 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1438 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs; 1435 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1439 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr); 1436 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1440 } 1437 }
1441 default: 1438 default:
1442 WARN_ON(1); 1439 WARN_ON(1);
1443 return false; /* don't expect to be here */ 1440 return false; /* don't expect to be here */
1444 } 1441 }
1445 } 1442 }
1446 1443
1447 /* 1444 /*
1448 * If no port is specified in addr structure, we try to match with 445 port 1445 * If no port is specified in addr structure, we try to match with 445 port
1449 * and if it fails - with 139 ports. It should be called only if address 1446 * and if it fails - with 139 ports. It should be called only if address
1450 * families of server and addr are equal. 1447 * families of server and addr are equal.
1451 */ 1448 */
1452 static bool 1449 static bool
1453 match_port(struct TCP_Server_Info *server, struct sockaddr *addr) 1450 match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
1454 { 1451 {
1455 unsigned short int port, *sport; 1452 unsigned short int port, *sport;
1456 1453
1457 switch (addr->sa_family) { 1454 switch (addr->sa_family) {
1458 case AF_INET: 1455 case AF_INET:
1459 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port; 1456 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
1460 port = ((struct sockaddr_in *) addr)->sin_port; 1457 port = ((struct sockaddr_in *) addr)->sin_port;
1461 break; 1458 break;
1462 case AF_INET6: 1459 case AF_INET6:
1463 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port; 1460 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
1464 port = ((struct sockaddr_in6 *) addr)->sin6_port; 1461 port = ((struct sockaddr_in6 *) addr)->sin6_port;
1465 break; 1462 break;
1466 default: 1463 default:
1467 WARN_ON(1); 1464 WARN_ON(1);
1468 return false; 1465 return false;
1469 } 1466 }
1470 1467
1471 if (!port) { 1468 if (!port) {
1472 port = htons(CIFS_PORT); 1469 port = htons(CIFS_PORT);
1473 if (port == *sport) 1470 if (port == *sport)
1474 return true; 1471 return true;
1475 1472
1476 port = htons(RFC1001_PORT); 1473 port = htons(RFC1001_PORT);
1477 } 1474 }
1478 1475
1479 return port == *sport; 1476 return port == *sport;
1480 } 1477 }
1481 1478
1482 static bool 1479 static bool
1483 match_address(struct TCP_Server_Info *server, struct sockaddr *addr, 1480 match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1484 struct sockaddr *srcaddr) 1481 struct sockaddr *srcaddr)
1485 { 1482 {
1486 switch (addr->sa_family) { 1483 switch (addr->sa_family) {
1487 case AF_INET: { 1484 case AF_INET: {
1488 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; 1485 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1489 struct sockaddr_in *srv_addr4 = 1486 struct sockaddr_in *srv_addr4 =
1490 (struct sockaddr_in *)&server->dstaddr; 1487 (struct sockaddr_in *)&server->dstaddr;
1491 1488
1492 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr) 1489 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
1493 return false; 1490 return false;
1494 break; 1491 break;
1495 } 1492 }
1496 case AF_INET6: { 1493 case AF_INET6: {
1497 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; 1494 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1498 struct sockaddr_in6 *srv_addr6 = 1495 struct sockaddr_in6 *srv_addr6 =
1499 (struct sockaddr_in6 *)&server->dstaddr; 1496 (struct sockaddr_in6 *)&server->dstaddr;
1500 1497
1501 if (!ipv6_addr_equal(&addr6->sin6_addr, 1498 if (!ipv6_addr_equal(&addr6->sin6_addr,
1502 &srv_addr6->sin6_addr)) 1499 &srv_addr6->sin6_addr))
1503 return false; 1500 return false;
1504 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id) 1501 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
1505 return false; 1502 return false;
1506 break; 1503 break;
1507 } 1504 }
1508 default: 1505 default:
1509 WARN_ON(1); 1506 WARN_ON(1);
1510 return false; /* don't expect to be here */ 1507 return false; /* don't expect to be here */
1511 } 1508 }
1512 1509
1513 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr)) 1510 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1514 return false; 1511 return false;
1515 1512
1516 return true; 1513 return true;
1517 } 1514 }
1518 1515
1519 static bool 1516 static bool
1520 match_security(struct TCP_Server_Info *server, struct smb_vol *vol) 1517 match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1521 { 1518 {
1522 unsigned int secFlags; 1519 unsigned int secFlags;
1523 1520
1524 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) 1521 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1525 secFlags = vol->secFlg; 1522 secFlags = vol->secFlg;
1526 else 1523 else
1527 secFlags = global_secflags | vol->secFlg; 1524 secFlags = global_secflags | vol->secFlg;
1528 1525
1529 switch (server->secType) { 1526 switch (server->secType) {
1530 case LANMAN: 1527 case LANMAN:
1531 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT))) 1528 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1532 return false; 1529 return false;
1533 break; 1530 break;
1534 case NTLMv2: 1531 case NTLMv2:
1535 if (!(secFlags & CIFSSEC_MAY_NTLMV2)) 1532 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1536 return false; 1533 return false;
1537 break; 1534 break;
1538 case NTLM: 1535 case NTLM:
1539 if (!(secFlags & CIFSSEC_MAY_NTLM)) 1536 if (!(secFlags & CIFSSEC_MAY_NTLM))
1540 return false; 1537 return false;
1541 break; 1538 break;
1542 case Kerberos: 1539 case Kerberos:
1543 if (!(secFlags & CIFSSEC_MAY_KRB5)) 1540 if (!(secFlags & CIFSSEC_MAY_KRB5))
1544 return false; 1541 return false;
1545 break; 1542 break;
1546 case RawNTLMSSP: 1543 case RawNTLMSSP:
1547 if (!(secFlags & CIFSSEC_MAY_NTLMSSP)) 1544 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1548 return false; 1545 return false;
1549 break; 1546 break;
1550 default: 1547 default:
1551 /* shouldn't happen */ 1548 /* shouldn't happen */
1552 return false; 1549 return false;
1553 } 1550 }
1554 1551
1555 /* now check if signing mode is acceptible */ 1552 /* now check if signing mode is acceptible */
1556 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 && 1553 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1557 (server->secMode & SECMODE_SIGN_REQUIRED)) 1554 (server->secMode & SECMODE_SIGN_REQUIRED))
1558 return false; 1555 return false;
1559 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) && 1556 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1560 (server->secMode & 1557 (server->secMode &
1561 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0) 1558 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1562 return false; 1559 return false;
1563 1560
1564 return true; 1561 return true;
1565 } 1562 }
1566 1563
1567 static struct TCP_Server_Info * 1564 static struct TCP_Server_Info *
1568 cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) 1565 cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1569 { 1566 {
1570 struct TCP_Server_Info *server; 1567 struct TCP_Server_Info *server;
1571 1568
1572 spin_lock(&cifs_tcp_ses_lock); 1569 spin_lock(&cifs_tcp_ses_lock);
1573 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 1570 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1574 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) 1571 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
1575 continue; 1572 continue;
1576 1573
1577 if (!match_address(server, addr, 1574 if (!match_address(server, addr,
1578 (struct sockaddr *)&vol->srcaddr)) 1575 (struct sockaddr *)&vol->srcaddr))
1579 continue; 1576 continue;
1580 1577
1581 if (!match_port(server, addr)) 1578 if (!match_port(server, addr))
1582 continue; 1579 continue;
1583 1580
1584 if (!match_security(server, vol)) 1581 if (!match_security(server, vol))
1585 continue; 1582 continue;
1586 1583
1587 ++server->srv_count; 1584 ++server->srv_count;
1588 spin_unlock(&cifs_tcp_ses_lock); 1585 spin_unlock(&cifs_tcp_ses_lock);
1589 cFYI(1, "Existing tcp session with server found"); 1586 cFYI(1, "Existing tcp session with server found");
1590 return server; 1587 return server;
1591 } 1588 }
1592 spin_unlock(&cifs_tcp_ses_lock); 1589 spin_unlock(&cifs_tcp_ses_lock);
1593 return NULL; 1590 return NULL;
1594 } 1591 }
1595 1592
1596 static void 1593 static void
1597 cifs_put_tcp_session(struct TCP_Server_Info *server) 1594 cifs_put_tcp_session(struct TCP_Server_Info *server)
1598 { 1595 {
1599 struct task_struct *task; 1596 struct task_struct *task;
1600 1597
1601 spin_lock(&cifs_tcp_ses_lock); 1598 spin_lock(&cifs_tcp_ses_lock);
1602 if (--server->srv_count > 0) { 1599 if (--server->srv_count > 0) {
1603 spin_unlock(&cifs_tcp_ses_lock); 1600 spin_unlock(&cifs_tcp_ses_lock);
1604 return; 1601 return;
1605 } 1602 }
1606 1603
1607 put_net(cifs_net_ns(server)); 1604 put_net(cifs_net_ns(server));
1608 1605
1609 list_del_init(&server->tcp_ses_list); 1606 list_del_init(&server->tcp_ses_list);
1610 spin_unlock(&cifs_tcp_ses_lock); 1607 spin_unlock(&cifs_tcp_ses_lock);
1611 1608
1612 cancel_delayed_work_sync(&server->echo); 1609 cancel_delayed_work_sync(&server->echo);
1613 1610
1614 spin_lock(&GlobalMid_Lock); 1611 spin_lock(&GlobalMid_Lock);
1615 server->tcpStatus = CifsExiting; 1612 server->tcpStatus = CifsExiting;
1616 spin_unlock(&GlobalMid_Lock); 1613 spin_unlock(&GlobalMid_Lock);
1617 1614
1618 cifs_crypto_shash_release(server); 1615 cifs_crypto_shash_release(server);
1619 cifs_fscache_release_client_cookie(server); 1616 cifs_fscache_release_client_cookie(server);
1620 1617
1621 kfree(server->session_key.response); 1618 kfree(server->session_key.response);
1622 server->session_key.response = NULL; 1619 server->session_key.response = NULL;
1623 server->session_key.len = 0; 1620 server->session_key.len = 0;
1624 1621
1625 task = xchg(&server->tsk, NULL); 1622 task = xchg(&server->tsk, NULL);
1626 if (task) 1623 if (task)
1627 force_sig(SIGKILL, task); 1624 force_sig(SIGKILL, task);
1628 } 1625 }
1629 1626
1630 static struct TCP_Server_Info * 1627 static struct TCP_Server_Info *
1631 cifs_get_tcp_session(struct smb_vol *volume_info) 1628 cifs_get_tcp_session(struct smb_vol *volume_info)
1632 { 1629 {
1633 struct TCP_Server_Info *tcp_ses = NULL; 1630 struct TCP_Server_Info *tcp_ses = NULL;
1634 struct sockaddr_storage addr; 1631 struct sockaddr_storage addr;
1635 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr; 1632 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1636 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr; 1633 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1637 int rc; 1634 int rc;
1638 1635
1639 memset(&addr, 0, sizeof(struct sockaddr_storage)); 1636 memset(&addr, 0, sizeof(struct sockaddr_storage));
1640 1637
1641 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip); 1638 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
1642 1639
1643 if (volume_info->UNCip && volume_info->UNC) { 1640 if (volume_info->UNCip && volume_info->UNC) {
1644 rc = cifs_fill_sockaddr((struct sockaddr *)&addr, 1641 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1645 volume_info->UNCip, 1642 volume_info->UNCip,
1646 strlen(volume_info->UNCip), 1643 strlen(volume_info->UNCip),
1647 volume_info->port); 1644 volume_info->port);
1648 if (!rc) { 1645 if (!rc) {
1649 /* we failed translating address */ 1646 /* we failed translating address */
1650 rc = -EINVAL; 1647 rc = -EINVAL;
1651 goto out_err; 1648 goto out_err;
1652 } 1649 }
1653 } else if (volume_info->UNCip) { 1650 } else if (volume_info->UNCip) {
1654 /* BB using ip addr as tcp_ses name to connect to the 1651 /* BB using ip addr as tcp_ses name to connect to the
1655 DFS root below */ 1652 DFS root below */
1656 cERROR(1, "Connecting to DFS root not implemented yet"); 1653 cERROR(1, "Connecting to DFS root not implemented yet");
1657 rc = -EINVAL; 1654 rc = -EINVAL;
1658 goto out_err; 1655 goto out_err;
1659 } else /* which tcp_sess DFS root would we conect to */ { 1656 } else /* which tcp_sess DFS root would we conect to */ {
1660 cERROR(1, "CIFS mount error: No UNC path (e.g. -o " 1657 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1661 "unc=//192.168.1.100/public) specified"); 1658 "unc=//192.168.1.100/public) specified");
1662 rc = -EINVAL; 1659 rc = -EINVAL;
1663 goto out_err; 1660 goto out_err;
1664 } 1661 }
1665 1662
1666 /* see if we already have a matching tcp_ses */ 1663 /* see if we already have a matching tcp_ses */
1667 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info); 1664 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
1668 if (tcp_ses) 1665 if (tcp_ses)
1669 return tcp_ses; 1666 return tcp_ses;
1670 1667
1671 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); 1668 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1672 if (!tcp_ses) { 1669 if (!tcp_ses) {
1673 rc = -ENOMEM; 1670 rc = -ENOMEM;
1674 goto out_err; 1671 goto out_err;
1675 } 1672 }
1676 1673
1677 rc = cifs_crypto_shash_allocate(tcp_ses); 1674 rc = cifs_crypto_shash_allocate(tcp_ses);
1678 if (rc) { 1675 if (rc) {
1679 cERROR(1, "could not setup hash structures rc %d", rc); 1676 cERROR(1, "could not setup hash structures rc %d", rc);
1680 goto out_err; 1677 goto out_err;
1681 } 1678 }
1682 1679
1683 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns)); 1680 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
1684 tcp_ses->hostname = extract_hostname(volume_info->UNC); 1681 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1685 if (IS_ERR(tcp_ses->hostname)) { 1682 if (IS_ERR(tcp_ses->hostname)) {
1686 rc = PTR_ERR(tcp_ses->hostname); 1683 rc = PTR_ERR(tcp_ses->hostname);
1687 goto out_err_crypto_release; 1684 goto out_err_crypto_release;
1688 } 1685 }
1689 1686
1690 tcp_ses->noblocksnd = volume_info->noblocksnd; 1687 tcp_ses->noblocksnd = volume_info->noblocksnd;
1691 tcp_ses->noautotune = volume_info->noautotune; 1688 tcp_ses->noautotune = volume_info->noautotune;
1692 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay; 1689 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
1693 atomic_set(&tcp_ses->inFlight, 0); 1690 atomic_set(&tcp_ses->inFlight, 0);
1694 init_waitqueue_head(&tcp_ses->response_q); 1691 init_waitqueue_head(&tcp_ses->response_q);
1695 init_waitqueue_head(&tcp_ses->request_q); 1692 init_waitqueue_head(&tcp_ses->request_q);
1696 INIT_LIST_HEAD(&tcp_ses->pending_mid_q); 1693 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1697 mutex_init(&tcp_ses->srv_mutex); 1694 mutex_init(&tcp_ses->srv_mutex);
1698 memcpy(tcp_ses->workstation_RFC1001_name, 1695 memcpy(tcp_ses->workstation_RFC1001_name,
1699 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 1696 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1700 memcpy(tcp_ses->server_RFC1001_name, 1697 memcpy(tcp_ses->server_RFC1001_name,
1701 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 1698 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1702 tcp_ses->session_estab = false; 1699 tcp_ses->session_estab = false;
1703 tcp_ses->sequence_number = 0; 1700 tcp_ses->sequence_number = 0;
1704 tcp_ses->lstrp = jiffies; 1701 tcp_ses->lstrp = jiffies;
1705 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 1702 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1706 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); 1703 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1707 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); 1704 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
1708 1705
1709 /* 1706 /*
1710 * at this point we are the only ones with the pointer 1707 * at this point we are the only ones with the pointer
1711 * to the struct since the kernel thread not created yet 1708 * to the struct since the kernel thread not created yet
1712 * no need to spinlock this init of tcpStatus or srv_count 1709 * no need to spinlock this init of tcpStatus or srv_count
1713 */ 1710 */
1714 tcp_ses->tcpStatus = CifsNew; 1711 tcp_ses->tcpStatus = CifsNew;
1715 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, 1712 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1716 sizeof(tcp_ses->srcaddr)); 1713 sizeof(tcp_ses->srcaddr));
1717 ++tcp_ses->srv_count; 1714 ++tcp_ses->srv_count;
1718 1715
1719 if (addr.ss_family == AF_INET6) { 1716 if (addr.ss_family == AF_INET6) {
1720 cFYI(1, "attempting ipv6 connect"); 1717 cFYI(1, "attempting ipv6 connect");
1721 /* BB should we allow ipv6 on port 139? */ 1718 /* BB should we allow ipv6 on port 139? */
1722 /* other OS never observed in Wild doing 139 with v6 */ 1719 /* other OS never observed in Wild doing 139 with v6 */
1723 memcpy(&tcp_ses->dstaddr, sin_server6, 1720 memcpy(&tcp_ses->dstaddr, sin_server6,
1724 sizeof(struct sockaddr_in6)); 1721 sizeof(struct sockaddr_in6));
1725 } else 1722 } else
1726 memcpy(&tcp_ses->dstaddr, sin_server, 1723 memcpy(&tcp_ses->dstaddr, sin_server,
1727 sizeof(struct sockaddr_in)); 1724 sizeof(struct sockaddr_in));
1728 1725
1729 rc = ip_connect(tcp_ses); 1726 rc = ip_connect(tcp_ses);
1730 if (rc < 0) { 1727 if (rc < 0) {
1731 cERROR(1, "Error connecting to socket. Aborting operation"); 1728 cERROR(1, "Error connecting to socket. Aborting operation");
1732 goto out_err_crypto_release; 1729 goto out_err_crypto_release;
1733 } 1730 }
1734 1731
1735 /* 1732 /*
1736 * since we're in a cifs function already, we know that 1733 * since we're in a cifs function already, we know that
1737 * this will succeed. No need for try_module_get(). 1734 * this will succeed. No need for try_module_get().
1738 */ 1735 */
1739 __module_get(THIS_MODULE); 1736 __module_get(THIS_MODULE);
1740 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, 1737 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1741 tcp_ses, "cifsd"); 1738 tcp_ses, "cifsd");
1742 if (IS_ERR(tcp_ses->tsk)) { 1739 if (IS_ERR(tcp_ses->tsk)) {
1743 rc = PTR_ERR(tcp_ses->tsk); 1740 rc = PTR_ERR(tcp_ses->tsk);
1744 cERROR(1, "error %d create cifsd thread", rc); 1741 cERROR(1, "error %d create cifsd thread", rc);
1745 module_put(THIS_MODULE); 1742 module_put(THIS_MODULE);
1746 goto out_err_crypto_release; 1743 goto out_err_crypto_release;
1747 } 1744 }
1748 1745
1749 /* thread spawned, put it on the list */ 1746 /* thread spawned, put it on the list */
1750 spin_lock(&cifs_tcp_ses_lock); 1747 spin_lock(&cifs_tcp_ses_lock);
1751 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); 1748 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1752 spin_unlock(&cifs_tcp_ses_lock); 1749 spin_unlock(&cifs_tcp_ses_lock);
1753 1750
1754 cifs_fscache_get_client_cookie(tcp_ses); 1751 cifs_fscache_get_client_cookie(tcp_ses);
1755 1752
1756 /* queue echo request delayed work */ 1753 /* queue echo request delayed work */
1757 queue_delayed_work(system_nrt_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL); 1754 queue_delayed_work(system_nrt_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL);
1758 1755
1759 return tcp_ses; 1756 return tcp_ses;
1760 1757
1761 out_err_crypto_release: 1758 out_err_crypto_release:
1762 cifs_crypto_shash_release(tcp_ses); 1759 cifs_crypto_shash_release(tcp_ses);
1763 1760
1764 put_net(cifs_net_ns(tcp_ses)); 1761 put_net(cifs_net_ns(tcp_ses));
1765 1762
1766 out_err: 1763 out_err:
1767 if (tcp_ses) { 1764 if (tcp_ses) {
1768 if (!IS_ERR(tcp_ses->hostname)) 1765 if (!IS_ERR(tcp_ses->hostname))
1769 kfree(tcp_ses->hostname); 1766 kfree(tcp_ses->hostname);
1770 if (tcp_ses->ssocket) 1767 if (tcp_ses->ssocket)
1771 sock_release(tcp_ses->ssocket); 1768 sock_release(tcp_ses->ssocket);
1772 kfree(tcp_ses); 1769 kfree(tcp_ses);
1773 } 1770 }
1774 return ERR_PTR(rc); 1771 return ERR_PTR(rc);
1775 } 1772 }
1776 1773
1777 static struct cifsSesInfo * 1774 static struct cifsSesInfo *
1778 cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) 1775 cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1779 { 1776 {
1780 struct cifsSesInfo *ses; 1777 struct cifsSesInfo *ses;
1781 1778
1782 spin_lock(&cifs_tcp_ses_lock); 1779 spin_lock(&cifs_tcp_ses_lock);
1783 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 1780 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1784 switch (server->secType) { 1781 switch (server->secType) {
1785 case Kerberos: 1782 case Kerberos:
1786 if (vol->cred_uid != ses->cred_uid) 1783 if (vol->cred_uid != ses->cred_uid)
1787 continue; 1784 continue;
1788 break; 1785 break;
1789 default: 1786 default:
1790 /* anything else takes username/password */ 1787 /* anything else takes username/password */
1791 if (strncmp(ses->userName, vol->username, 1788 if (strncmp(ses->userName, vol->username,
1792 MAX_USERNAME_SIZE)) 1789 MAX_USERNAME_SIZE))
1793 continue; 1790 continue;
1794 if (strlen(vol->username) != 0 && 1791 if (strlen(vol->username) != 0 &&
1795 ses->password != NULL && 1792 ses->password != NULL &&
1796 strncmp(ses->password, 1793 strncmp(ses->password,
1797 vol->password ? vol->password : "", 1794 vol->password ? vol->password : "",
1798 MAX_PASSWORD_SIZE)) 1795 MAX_PASSWORD_SIZE))
1799 continue; 1796 continue;
1800 } 1797 }
1801 ++ses->ses_count; 1798 ++ses->ses_count;
1802 spin_unlock(&cifs_tcp_ses_lock); 1799 spin_unlock(&cifs_tcp_ses_lock);
1803 return ses; 1800 return ses;
1804 } 1801 }
1805 spin_unlock(&cifs_tcp_ses_lock); 1802 spin_unlock(&cifs_tcp_ses_lock);
1806 return NULL; 1803 return NULL;
1807 } 1804 }
1808 1805
1809 static void 1806 static void
1810 cifs_put_smb_ses(struct cifsSesInfo *ses) 1807 cifs_put_smb_ses(struct cifsSesInfo *ses)
1811 { 1808 {
1812 int xid; 1809 int xid;
1813 struct TCP_Server_Info *server = ses->server; 1810 struct TCP_Server_Info *server = ses->server;
1814 1811
1815 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count); 1812 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1816 spin_lock(&cifs_tcp_ses_lock); 1813 spin_lock(&cifs_tcp_ses_lock);
1817 if (--ses->ses_count > 0) { 1814 if (--ses->ses_count > 0) {
1818 spin_unlock(&cifs_tcp_ses_lock); 1815 spin_unlock(&cifs_tcp_ses_lock);
1819 return; 1816 return;
1820 } 1817 }
1821 1818
1822 list_del_init(&ses->smb_ses_list); 1819 list_del_init(&ses->smb_ses_list);
1823 spin_unlock(&cifs_tcp_ses_lock); 1820 spin_unlock(&cifs_tcp_ses_lock);
1824 1821
1825 if (ses->status == CifsGood) { 1822 if (ses->status == CifsGood) {
1826 xid = GetXid(); 1823 xid = GetXid();
1827 CIFSSMBLogoff(xid, ses); 1824 CIFSSMBLogoff(xid, ses);
1828 _FreeXid(xid); 1825 _FreeXid(xid);
1829 } 1826 }
1830 sesInfoFree(ses); 1827 sesInfoFree(ses);
1831 cifs_put_tcp_session(server); 1828 cifs_put_tcp_session(server);
1832 } 1829 }
1833 1830
1834 static struct cifsSesInfo * 1831 static struct cifsSesInfo *
1835 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) 1832 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1836 { 1833 {
1837 int rc = -ENOMEM, xid; 1834 int rc = -ENOMEM, xid;
1838 struct cifsSesInfo *ses; 1835 struct cifsSesInfo *ses;
1839 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; 1836 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
1840 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; 1837 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
1841 1838
1842 xid = GetXid(); 1839 xid = GetXid();
1843 1840
1844 ses = cifs_find_smb_ses(server, volume_info); 1841 ses = cifs_find_smb_ses(server, volume_info);
1845 if (ses) { 1842 if (ses) {
1846 cFYI(1, "Existing smb sess found (status=%d)", ses->status); 1843 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1847 1844
1848 mutex_lock(&ses->session_mutex); 1845 mutex_lock(&ses->session_mutex);
1849 rc = cifs_negotiate_protocol(xid, ses); 1846 rc = cifs_negotiate_protocol(xid, ses);
1850 if (rc) { 1847 if (rc) {
1851 mutex_unlock(&ses->session_mutex); 1848 mutex_unlock(&ses->session_mutex);
1852 /* problem -- put our ses reference */ 1849 /* problem -- put our ses reference */
1853 cifs_put_smb_ses(ses); 1850 cifs_put_smb_ses(ses);
1854 FreeXid(xid); 1851 FreeXid(xid);
1855 return ERR_PTR(rc); 1852 return ERR_PTR(rc);
1856 } 1853 }
1857 if (ses->need_reconnect) { 1854 if (ses->need_reconnect) {
1858 cFYI(1, "Session needs reconnect"); 1855 cFYI(1, "Session needs reconnect");
1859 rc = cifs_setup_session(xid, ses, 1856 rc = cifs_setup_session(xid, ses,
1860 volume_info->local_nls); 1857 volume_info->local_nls);
1861 if (rc) { 1858 if (rc) {
1862 mutex_unlock(&ses->session_mutex); 1859 mutex_unlock(&ses->session_mutex);
1863 /* problem -- put our reference */ 1860 /* problem -- put our reference */
1864 cifs_put_smb_ses(ses); 1861 cifs_put_smb_ses(ses);
1865 FreeXid(xid); 1862 FreeXid(xid);
1866 return ERR_PTR(rc); 1863 return ERR_PTR(rc);
1867 } 1864 }
1868 } 1865 }
1869 mutex_unlock(&ses->session_mutex); 1866 mutex_unlock(&ses->session_mutex);
1870 1867
1871 /* existing SMB ses has a server reference already */ 1868 /* existing SMB ses has a server reference already */
1872 cifs_put_tcp_session(server); 1869 cifs_put_tcp_session(server);
1873 FreeXid(xid); 1870 FreeXid(xid);
1874 return ses; 1871 return ses;
1875 } 1872 }
1876 1873
1877 cFYI(1, "Existing smb sess not found"); 1874 cFYI(1, "Existing smb sess not found");
1878 ses = sesInfoAlloc(); 1875 ses = sesInfoAlloc();
1879 if (ses == NULL) 1876 if (ses == NULL)
1880 goto get_ses_fail; 1877 goto get_ses_fail;
1881 1878
1882 /* new SMB session uses our server ref */ 1879 /* new SMB session uses our server ref */
1883 ses->server = server; 1880 ses->server = server;
1884 if (server->dstaddr.ss_family == AF_INET6) 1881 if (server->dstaddr.ss_family == AF_INET6)
1885 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr); 1882 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
1886 else 1883 else
1887 sprintf(ses->serverName, "%pI4", &addr->sin_addr); 1884 sprintf(ses->serverName, "%pI4", &addr->sin_addr);
1888 1885
1889 if (volume_info->username) 1886 if (volume_info->username)
1890 strncpy(ses->userName, volume_info->username, 1887 strncpy(ses->userName, volume_info->username,
1891 MAX_USERNAME_SIZE); 1888 MAX_USERNAME_SIZE);
1892 1889
1893 /* volume_info->password freed at unmount */ 1890 /* volume_info->password freed at unmount */
1894 if (volume_info->password) { 1891 if (volume_info->password) {
1895 ses->password = kstrdup(volume_info->password, GFP_KERNEL); 1892 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1896 if (!ses->password) 1893 if (!ses->password)
1897 goto get_ses_fail; 1894 goto get_ses_fail;
1898 } 1895 }
1899 if (volume_info->domainname) { 1896 if (volume_info->domainname) {
1900 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL); 1897 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
1901 if (!ses->domainName) 1898 if (!ses->domainName)
1902 goto get_ses_fail; 1899 goto get_ses_fail;
1903 } 1900 }
1904 ses->cred_uid = volume_info->cred_uid; 1901 ses->cred_uid = volume_info->cred_uid;
1905 ses->linux_uid = volume_info->linux_uid; 1902 ses->linux_uid = volume_info->linux_uid;
1906 ses->overrideSecFlg = volume_info->secFlg; 1903 ses->overrideSecFlg = volume_info->secFlg;
1907 1904
1908 mutex_lock(&ses->session_mutex); 1905 mutex_lock(&ses->session_mutex);
1909 rc = cifs_negotiate_protocol(xid, ses); 1906 rc = cifs_negotiate_protocol(xid, ses);
1910 if (!rc) 1907 if (!rc)
1911 rc = cifs_setup_session(xid, ses, volume_info->local_nls); 1908 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1912 mutex_unlock(&ses->session_mutex); 1909 mutex_unlock(&ses->session_mutex);
1913 if (rc) 1910 if (rc)
1914 goto get_ses_fail; 1911 goto get_ses_fail;
1915 1912
1916 /* success, put it on the list */ 1913 /* success, put it on the list */
1917 spin_lock(&cifs_tcp_ses_lock); 1914 spin_lock(&cifs_tcp_ses_lock);
1918 list_add(&ses->smb_ses_list, &server->smb_ses_list); 1915 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1919 spin_unlock(&cifs_tcp_ses_lock); 1916 spin_unlock(&cifs_tcp_ses_lock);
1920 1917
1921 FreeXid(xid); 1918 FreeXid(xid);
1922 return ses; 1919 return ses;
1923 1920
1924 get_ses_fail: 1921 get_ses_fail:
1925 sesInfoFree(ses); 1922 sesInfoFree(ses);
1926 FreeXid(xid); 1923 FreeXid(xid);
1927 return ERR_PTR(rc); 1924 return ERR_PTR(rc);
1928 } 1925 }
1929 1926
1930 static struct cifsTconInfo * 1927 static struct cifsTconInfo *
1931 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) 1928 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1932 { 1929 {
1933 struct list_head *tmp; 1930 struct list_head *tmp;
1934 struct cifsTconInfo *tcon; 1931 struct cifsTconInfo *tcon;
1935 1932
1936 spin_lock(&cifs_tcp_ses_lock); 1933 spin_lock(&cifs_tcp_ses_lock);
1937 list_for_each(tmp, &ses->tcon_list) { 1934 list_for_each(tmp, &ses->tcon_list) {
1938 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); 1935 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1939 if (tcon->tidStatus == CifsExiting) 1936 if (tcon->tidStatus == CifsExiting)
1940 continue; 1937 continue;
1941 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE)) 1938 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1942 continue; 1939 continue;
1943 1940
1944 ++tcon->tc_count; 1941 ++tcon->tc_count;
1945 spin_unlock(&cifs_tcp_ses_lock); 1942 spin_unlock(&cifs_tcp_ses_lock);
1946 return tcon; 1943 return tcon;
1947 } 1944 }
1948 spin_unlock(&cifs_tcp_ses_lock); 1945 spin_unlock(&cifs_tcp_ses_lock);
1949 return NULL; 1946 return NULL;
1950 } 1947 }
1951 1948
1952 static void 1949 static void
1953 cifs_put_tcon(struct cifsTconInfo *tcon) 1950 cifs_put_tcon(struct cifsTconInfo *tcon)
1954 { 1951 {
1955 int xid; 1952 int xid;
1956 struct cifsSesInfo *ses = tcon->ses; 1953 struct cifsSesInfo *ses = tcon->ses;
1957 1954
1958 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count); 1955 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1959 spin_lock(&cifs_tcp_ses_lock); 1956 spin_lock(&cifs_tcp_ses_lock);
1960 if (--tcon->tc_count > 0) { 1957 if (--tcon->tc_count > 0) {
1961 spin_unlock(&cifs_tcp_ses_lock); 1958 spin_unlock(&cifs_tcp_ses_lock);
1962 return; 1959 return;
1963 } 1960 }
1964 1961
1965 list_del_init(&tcon->tcon_list); 1962 list_del_init(&tcon->tcon_list);
1966 spin_unlock(&cifs_tcp_ses_lock); 1963 spin_unlock(&cifs_tcp_ses_lock);
1967 1964
1968 xid = GetXid(); 1965 xid = GetXid();
1969 CIFSSMBTDis(xid, tcon); 1966 CIFSSMBTDis(xid, tcon);
1970 _FreeXid(xid); 1967 _FreeXid(xid);
1971 1968
1972 cifs_fscache_release_super_cookie(tcon); 1969 cifs_fscache_release_super_cookie(tcon);
1973 tconInfoFree(tcon); 1970 tconInfoFree(tcon);
1974 cifs_put_smb_ses(ses); 1971 cifs_put_smb_ses(ses);
1975 } 1972 }
1976 1973
1977 static struct cifsTconInfo * 1974 static struct cifsTconInfo *
1978 cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info) 1975 cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1979 { 1976 {
1980 int rc, xid; 1977 int rc, xid;
1981 struct cifsTconInfo *tcon; 1978 struct cifsTconInfo *tcon;
1982 1979
1983 tcon = cifs_find_tcon(ses, volume_info->UNC); 1980 tcon = cifs_find_tcon(ses, volume_info->UNC);
1984 if (tcon) { 1981 if (tcon) {
1985 cFYI(1, "Found match on UNC path"); 1982 cFYI(1, "Found match on UNC path");
1986 /* existing tcon already has a reference */ 1983 /* existing tcon already has a reference */
1987 cifs_put_smb_ses(ses); 1984 cifs_put_smb_ses(ses);
1988 if (tcon->seal != volume_info->seal) 1985 if (tcon->seal != volume_info->seal)
1989 cERROR(1, "transport encryption setting " 1986 cERROR(1, "transport encryption setting "
1990 "conflicts with existing tid"); 1987 "conflicts with existing tid");
1991 return tcon; 1988 return tcon;
1992 } 1989 }
1993 1990
1994 tcon = tconInfoAlloc(); 1991 tcon = tconInfoAlloc();
1995 if (tcon == NULL) { 1992 if (tcon == NULL) {
1996 rc = -ENOMEM; 1993 rc = -ENOMEM;
1997 goto out_fail; 1994 goto out_fail;
1998 } 1995 }
1999 1996
2000 tcon->ses = ses; 1997 tcon->ses = ses;
2001 if (volume_info->password) { 1998 if (volume_info->password) {
2002 tcon->password = kstrdup(volume_info->password, GFP_KERNEL); 1999 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
2003 if (!tcon->password) { 2000 if (!tcon->password) {
2004 rc = -ENOMEM; 2001 rc = -ENOMEM;
2005 goto out_fail; 2002 goto out_fail;
2006 } 2003 }
2007 } 2004 }
2008 2005
2009 if (strchr(volume_info->UNC + 3, '\\') == NULL 2006 if (strchr(volume_info->UNC + 3, '\\') == NULL
2010 && strchr(volume_info->UNC + 3, '/') == NULL) { 2007 && strchr(volume_info->UNC + 3, '/') == NULL) {
2011 cERROR(1, "Missing share name"); 2008 cERROR(1, "Missing share name");
2012 rc = -ENODEV; 2009 rc = -ENODEV;
2013 goto out_fail; 2010 goto out_fail;
2014 } 2011 }
2015 2012
2016 /* BB Do we need to wrap session_mutex around 2013 /* BB Do we need to wrap session_mutex around
2017 * this TCon call and Unix SetFS as 2014 * this TCon call and Unix SetFS as
2018 * we do on SessSetup and reconnect? */ 2015 * we do on SessSetup and reconnect? */
2019 xid = GetXid(); 2016 xid = GetXid();
2020 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls); 2017 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
2021 FreeXid(xid); 2018 FreeXid(xid);
2022 cFYI(1, "CIFS Tcon rc = %d", rc); 2019 cFYI(1, "CIFS Tcon rc = %d", rc);
2023 if (rc) 2020 if (rc)
2024 goto out_fail; 2021 goto out_fail;
2025 2022
2026 if (volume_info->nodfs) { 2023 if (volume_info->nodfs) {
2027 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; 2024 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2028 cFYI(1, "DFS disabled (%d)", tcon->Flags); 2025 cFYI(1, "DFS disabled (%d)", tcon->Flags);
2029 } 2026 }
2030 tcon->seal = volume_info->seal; 2027 tcon->seal = volume_info->seal;
2031 /* we can have only one retry value for a connection 2028 /* we can have only one retry value for a connection
2032 to a share so for resources mounted more than once 2029 to a share so for resources mounted more than once
2033 to the same server share the last value passed in 2030 to the same server share the last value passed in
2034 for the retry flag is used */ 2031 for the retry flag is used */
2035 tcon->retry = volume_info->retry; 2032 tcon->retry = volume_info->retry;
2036 tcon->nocase = volume_info->nocase; 2033 tcon->nocase = volume_info->nocase;
2037 tcon->local_lease = volume_info->local_lease; 2034 tcon->local_lease = volume_info->local_lease;
2038 2035
2039 spin_lock(&cifs_tcp_ses_lock); 2036 spin_lock(&cifs_tcp_ses_lock);
2040 list_add(&tcon->tcon_list, &ses->tcon_list); 2037 list_add(&tcon->tcon_list, &ses->tcon_list);
2041 spin_unlock(&cifs_tcp_ses_lock); 2038 spin_unlock(&cifs_tcp_ses_lock);
2042 2039
2043 cifs_fscache_get_super_cookie(tcon); 2040 cifs_fscache_get_super_cookie(tcon);
2044 2041
2045 return tcon; 2042 return tcon;
2046 2043
2047 out_fail: 2044 out_fail:
2048 tconInfoFree(tcon); 2045 tconInfoFree(tcon);
2049 return ERR_PTR(rc); 2046 return ERR_PTR(rc);
2050 } 2047 }
2051 2048
2052 void 2049 void
2053 cifs_put_tlink(struct tcon_link *tlink) 2050 cifs_put_tlink(struct tcon_link *tlink)
2054 { 2051 {
2055 if (!tlink || IS_ERR(tlink)) 2052 if (!tlink || IS_ERR(tlink))
2056 return; 2053 return;
2057 2054
2058 if (!atomic_dec_and_test(&tlink->tl_count) || 2055 if (!atomic_dec_and_test(&tlink->tl_count) ||
2059 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) { 2056 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
2060 tlink->tl_time = jiffies; 2057 tlink->tl_time = jiffies;
2061 return; 2058 return;
2062 } 2059 }
2063 2060
2064 if (!IS_ERR(tlink_tcon(tlink))) 2061 if (!IS_ERR(tlink_tcon(tlink)))
2065 cifs_put_tcon(tlink_tcon(tlink)); 2062 cifs_put_tcon(tlink_tcon(tlink));
2066 kfree(tlink); 2063 kfree(tlink);
2067 return; 2064 return;
2068 } 2065 }
2069 2066
2070 int 2067 int
2071 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 2068 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
2072 const struct nls_table *nls_codepage, unsigned int *pnum_referrals, 2069 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
2073 struct dfs_info3_param **preferrals, int remap) 2070 struct dfs_info3_param **preferrals, int remap)
2074 { 2071 {
2075 char *temp_unc; 2072 char *temp_unc;
2076 int rc = 0; 2073 int rc = 0;
2077 2074
2078 *pnum_referrals = 0; 2075 *pnum_referrals = 0;
2079 *preferrals = NULL; 2076 *preferrals = NULL;
2080 2077
2081 if (pSesInfo->ipc_tid == 0) { 2078 if (pSesInfo->ipc_tid == 0) {
2082 temp_unc = kmalloc(2 /* for slashes */ + 2079 temp_unc = kmalloc(2 /* for slashes */ +
2083 strnlen(pSesInfo->serverName, 2080 strnlen(pSesInfo->serverName,
2084 SERVER_NAME_LEN_WITH_NULL * 2) 2081 SERVER_NAME_LEN_WITH_NULL * 2)
2085 + 1 + 4 /* slash IPC$ */ + 2, 2082 + 1 + 4 /* slash IPC$ */ + 2,
2086 GFP_KERNEL); 2083 GFP_KERNEL);
2087 if (temp_unc == NULL) 2084 if (temp_unc == NULL)
2088 return -ENOMEM; 2085 return -ENOMEM;
2089 temp_unc[0] = '\\'; 2086 temp_unc[0] = '\\';
2090 temp_unc[1] = '\\'; 2087 temp_unc[1] = '\\';
2091 strcpy(temp_unc + 2, pSesInfo->serverName); 2088 strcpy(temp_unc + 2, pSesInfo->serverName);
2092 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$"); 2089 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
2093 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage); 2090 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
2094 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid); 2091 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
2095 kfree(temp_unc); 2092 kfree(temp_unc);
2096 } 2093 }
2097 if (rc == 0) 2094 if (rc == 0)
2098 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, 2095 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
2099 pnum_referrals, nls_codepage, remap); 2096 pnum_referrals, nls_codepage, remap);
2100 /* BB map targetUNCs to dfs_info3 structures, here or 2097 /* BB map targetUNCs to dfs_info3 structures, here or
2101 in CIFSGetDFSRefer BB */ 2098 in CIFSGetDFSRefer BB */
2102 2099
2103 return rc; 2100 return rc;
2104 } 2101 }
2105 2102
2106 #ifdef CONFIG_DEBUG_LOCK_ALLOC 2103 #ifdef CONFIG_DEBUG_LOCK_ALLOC
2107 static struct lock_class_key cifs_key[2]; 2104 static struct lock_class_key cifs_key[2];
2108 static struct lock_class_key cifs_slock_key[2]; 2105 static struct lock_class_key cifs_slock_key[2];
2109 2106
2110 static inline void 2107 static inline void
2111 cifs_reclassify_socket4(struct socket *sock) 2108 cifs_reclassify_socket4(struct socket *sock)
2112 { 2109 {
2113 struct sock *sk = sock->sk; 2110 struct sock *sk = sock->sk;
2114 BUG_ON(sock_owned_by_user(sk)); 2111 BUG_ON(sock_owned_by_user(sk));
2115 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS", 2112 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
2116 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]); 2113 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
2117 } 2114 }
2118 2115
2119 static inline void 2116 static inline void
2120 cifs_reclassify_socket6(struct socket *sock) 2117 cifs_reclassify_socket6(struct socket *sock)
2121 { 2118 {
2122 struct sock *sk = sock->sk; 2119 struct sock *sk = sock->sk;
2123 BUG_ON(sock_owned_by_user(sk)); 2120 BUG_ON(sock_owned_by_user(sk));
2124 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS", 2121 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
2125 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]); 2122 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
2126 } 2123 }
2127 #else 2124 #else
2128 static inline void 2125 static inline void
2129 cifs_reclassify_socket4(struct socket *sock) 2126 cifs_reclassify_socket4(struct socket *sock)
2130 { 2127 {
2131 } 2128 }
2132 2129
2133 static inline void 2130 static inline void
2134 cifs_reclassify_socket6(struct socket *sock) 2131 cifs_reclassify_socket6(struct socket *sock)
2135 { 2132 {
2136 } 2133 }
2137 #endif 2134 #endif
2138 2135
2139 /* See RFC1001 section 14 on representation of Netbios names */ 2136 /* See RFC1001 section 14 on representation of Netbios names */
2140 static void rfc1002mangle(char *target, char *source, unsigned int length) 2137 static void rfc1002mangle(char *target, char *source, unsigned int length)
2141 { 2138 {
2142 unsigned int i, j; 2139 unsigned int i, j;
2143 2140
2144 for (i = 0, j = 0; i < (length); i++) { 2141 for (i = 0, j = 0; i < (length); i++) {
2145 /* mask a nibble at a time and encode */ 2142 /* mask a nibble at a time and encode */
2146 target[j] = 'A' + (0x0F & (source[i] >> 4)); 2143 target[j] = 'A' + (0x0F & (source[i] >> 4));
2147 target[j+1] = 'A' + (0x0F & source[i]); 2144 target[j+1] = 'A' + (0x0F & source[i]);
2148 j += 2; 2145 j += 2;
2149 } 2146 }
2150 2147
2151 } 2148 }
2152 2149
2153 static int 2150 static int
2154 bind_socket(struct TCP_Server_Info *server) 2151 bind_socket(struct TCP_Server_Info *server)
2155 { 2152 {
2156 int rc = 0; 2153 int rc = 0;
2157 if (server->srcaddr.ss_family != AF_UNSPEC) { 2154 if (server->srcaddr.ss_family != AF_UNSPEC) {
2158 /* Bind to the specified local IP address */ 2155 /* Bind to the specified local IP address */
2159 struct socket *socket = server->ssocket; 2156 struct socket *socket = server->ssocket;
2160 rc = socket->ops->bind(socket, 2157 rc = socket->ops->bind(socket,
2161 (struct sockaddr *) &server->srcaddr, 2158 (struct sockaddr *) &server->srcaddr,
2162 sizeof(server->srcaddr)); 2159 sizeof(server->srcaddr));
2163 if (rc < 0) { 2160 if (rc < 0) {
2164 struct sockaddr_in *saddr4; 2161 struct sockaddr_in *saddr4;
2165 struct sockaddr_in6 *saddr6; 2162 struct sockaddr_in6 *saddr6;
2166 saddr4 = (struct sockaddr_in *)&server->srcaddr; 2163 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2167 saddr6 = (struct sockaddr_in6 *)&server->srcaddr; 2164 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2168 if (saddr6->sin6_family == AF_INET6) 2165 if (saddr6->sin6_family == AF_INET6)
2169 cERROR(1, "cifs: " 2166 cERROR(1, "cifs: "
2170 "Failed to bind to: %pI6c, error: %d\n", 2167 "Failed to bind to: %pI6c, error: %d\n",
2171 &saddr6->sin6_addr, rc); 2168 &saddr6->sin6_addr, rc);
2172 else 2169 else
2173 cERROR(1, "cifs: " 2170 cERROR(1, "cifs: "
2174 "Failed to bind to: %pI4, error: %d\n", 2171 "Failed to bind to: %pI4, error: %d\n",
2175 &saddr4->sin_addr.s_addr, rc); 2172 &saddr4->sin_addr.s_addr, rc);
2176 } 2173 }
2177 } 2174 }
2178 return rc; 2175 return rc;
2179 } 2176 }
2180 2177
2181 static int 2178 static int
2182 ip_rfc1001_connect(struct TCP_Server_Info *server) 2179 ip_rfc1001_connect(struct TCP_Server_Info *server)
2183 { 2180 {
2184 int rc = 0; 2181 int rc = 0;
2185 /* 2182 /*
2186 * some servers require RFC1001 sessinit before sending 2183 * some servers require RFC1001 sessinit before sending
2187 * negprot - BB check reconnection in case where second 2184 * negprot - BB check reconnection in case where second
2188 * sessinit is sent but no second negprot 2185 * sessinit is sent but no second negprot
2189 */ 2186 */
2190 struct rfc1002_session_packet *ses_init_buf; 2187 struct rfc1002_session_packet *ses_init_buf;
2191 struct smb_hdr *smb_buf; 2188 struct smb_hdr *smb_buf;
2192 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), 2189 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2193 GFP_KERNEL); 2190 GFP_KERNEL);
2194 if (ses_init_buf) { 2191 if (ses_init_buf) {
2195 ses_init_buf->trailer.session_req.called_len = 32; 2192 ses_init_buf->trailer.session_req.called_len = 32;
2196 2193
2197 if (server->server_RFC1001_name && 2194 if (server->server_RFC1001_name &&
2198 server->server_RFC1001_name[0] != 0) 2195 server->server_RFC1001_name[0] != 0)
2199 rfc1002mangle(ses_init_buf->trailer. 2196 rfc1002mangle(ses_init_buf->trailer.
2200 session_req.called_name, 2197 session_req.called_name,
2201 server->server_RFC1001_name, 2198 server->server_RFC1001_name,
2202 RFC1001_NAME_LEN_WITH_NULL); 2199 RFC1001_NAME_LEN_WITH_NULL);
2203 else 2200 else
2204 rfc1002mangle(ses_init_buf->trailer. 2201 rfc1002mangle(ses_init_buf->trailer.
2205 session_req.called_name, 2202 session_req.called_name,
2206 DEFAULT_CIFS_CALLED_NAME, 2203 DEFAULT_CIFS_CALLED_NAME,
2207 RFC1001_NAME_LEN_WITH_NULL); 2204 RFC1001_NAME_LEN_WITH_NULL);
2208 2205
2209 ses_init_buf->trailer.session_req.calling_len = 32; 2206 ses_init_buf->trailer.session_req.calling_len = 32;
2210 2207
2211 /* 2208 /*
2212 * calling name ends in null (byte 16) from old smb 2209 * calling name ends in null (byte 16) from old smb
2213 * convention. 2210 * convention.
2214 */ 2211 */
2215 if (server->workstation_RFC1001_name && 2212 if (server->workstation_RFC1001_name &&
2216 server->workstation_RFC1001_name[0] != 0) 2213 server->workstation_RFC1001_name[0] != 0)
2217 rfc1002mangle(ses_init_buf->trailer. 2214 rfc1002mangle(ses_init_buf->trailer.
2218 session_req.calling_name, 2215 session_req.calling_name,
2219 server->workstation_RFC1001_name, 2216 server->workstation_RFC1001_name,
2220 RFC1001_NAME_LEN_WITH_NULL); 2217 RFC1001_NAME_LEN_WITH_NULL);
2221 else 2218 else
2222 rfc1002mangle(ses_init_buf->trailer. 2219 rfc1002mangle(ses_init_buf->trailer.
2223 session_req.calling_name, 2220 session_req.calling_name,
2224 "LINUX_CIFS_CLNT", 2221 "LINUX_CIFS_CLNT",
2225 RFC1001_NAME_LEN_WITH_NULL); 2222 RFC1001_NAME_LEN_WITH_NULL);
2226 2223
2227 ses_init_buf->trailer.session_req.scope1 = 0; 2224 ses_init_buf->trailer.session_req.scope1 = 0;
2228 ses_init_buf->trailer.session_req.scope2 = 0; 2225 ses_init_buf->trailer.session_req.scope2 = 0;
2229 smb_buf = (struct smb_hdr *)ses_init_buf; 2226 smb_buf = (struct smb_hdr *)ses_init_buf;
2230 2227
2231 /* sizeof RFC1002_SESSION_REQUEST with no scope */ 2228 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2232 smb_buf->smb_buf_length = 0x81000044; 2229 smb_buf->smb_buf_length = 0x81000044;
2233 rc = smb_send(server, smb_buf, 0x44); 2230 rc = smb_send(server, smb_buf, 0x44);
2234 kfree(ses_init_buf); 2231 kfree(ses_init_buf);
2235 /* 2232 /*
2236 * RFC1001 layer in at least one server 2233 * RFC1001 layer in at least one server
2237 * requires very short break before negprot 2234 * requires very short break before negprot
2238 * presumably because not expecting negprot 2235 * presumably because not expecting negprot
2239 * to follow so fast. This is a simple 2236 * to follow so fast. This is a simple
2240 * solution that works without 2237 * solution that works without
2241 * complicating the code and causes no 2238 * complicating the code and causes no
2242 * significant slowing down on mount 2239 * significant slowing down on mount
2243 * for everyone else 2240 * for everyone else
2244 */ 2241 */
2245 usleep_range(1000, 2000); 2242 usleep_range(1000, 2000);
2246 } 2243 }
2247 /* 2244 /*
2248 * else the negprot may still work without this 2245 * else the negprot may still work without this
2249 * even though malloc failed 2246 * even though malloc failed
2250 */ 2247 */
2251 2248
2252 return rc; 2249 return rc;
2253 } 2250 }
2254 2251
2255 static int 2252 static int
2256 generic_ip_connect(struct TCP_Server_Info *server) 2253 generic_ip_connect(struct TCP_Server_Info *server)
2257 { 2254 {
2258 int rc = 0; 2255 int rc = 0;
2259 unsigned short int sport; 2256 unsigned short int sport;
2260 int slen, sfamily; 2257 int slen, sfamily;
2261 struct socket *socket = server->ssocket; 2258 struct socket *socket = server->ssocket;
2262 struct sockaddr *saddr; 2259 struct sockaddr *saddr;
2263 2260
2264 saddr = (struct sockaddr *) &server->dstaddr; 2261 saddr = (struct sockaddr *) &server->dstaddr;
2265 2262
2266 if (server->dstaddr.ss_family == AF_INET6) { 2263 if (server->dstaddr.ss_family == AF_INET6) {
2267 sport = ((struct sockaddr_in6 *) saddr)->sin6_port; 2264 sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
2268 slen = sizeof(struct sockaddr_in6); 2265 slen = sizeof(struct sockaddr_in6);
2269 sfamily = AF_INET6; 2266 sfamily = AF_INET6;
2270 } else { 2267 } else {
2271 sport = ((struct sockaddr_in *) saddr)->sin_port; 2268 sport = ((struct sockaddr_in *) saddr)->sin_port;
2272 slen = sizeof(struct sockaddr_in); 2269 slen = sizeof(struct sockaddr_in);
2273 sfamily = AF_INET; 2270 sfamily = AF_INET;
2274 } 2271 }
2275 2272
2276 if (socket == NULL) { 2273 if (socket == NULL) {
2277 rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM, 2274 rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
2278 IPPROTO_TCP, &socket, 1); 2275 IPPROTO_TCP, &socket, 1);
2279 if (rc < 0) { 2276 if (rc < 0) {
2280 cERROR(1, "Error %d creating socket", rc); 2277 cERROR(1, "Error %d creating socket", rc);
2281 server->ssocket = NULL; 2278 server->ssocket = NULL;
2282 return rc; 2279 return rc;
2283 } 2280 }
2284 2281
2285 /* BB other socket options to set KEEPALIVE, NODELAY? */ 2282 /* BB other socket options to set KEEPALIVE, NODELAY? */
2286 cFYI(1, "Socket created"); 2283 cFYI(1, "Socket created");
2287 server->ssocket = socket; 2284 server->ssocket = socket;
2288 socket->sk->sk_allocation = GFP_NOFS; 2285 socket->sk->sk_allocation = GFP_NOFS;
2289 if (sfamily == AF_INET6) 2286 if (sfamily == AF_INET6)
2290 cifs_reclassify_socket6(socket); 2287 cifs_reclassify_socket6(socket);
2291 else 2288 else
2292 cifs_reclassify_socket4(socket); 2289 cifs_reclassify_socket4(socket);
2293 } 2290 }
2294 2291
2295 rc = bind_socket(server); 2292 rc = bind_socket(server);
2296 if (rc < 0) 2293 if (rc < 0)
2297 return rc; 2294 return rc;
2298 2295
2299 rc = socket->ops->connect(socket, saddr, slen, 0); 2296 rc = socket->ops->connect(socket, saddr, slen, 0);
2300 if (rc < 0) { 2297 if (rc < 0) {
2301 cFYI(1, "Error %d connecting to server", rc); 2298 cFYI(1, "Error %d connecting to server", rc);
2302 sock_release(socket); 2299 sock_release(socket);
2303 server->ssocket = NULL; 2300 server->ssocket = NULL;
2304 return rc; 2301 return rc;
2305 } 2302 }
2306 2303
2307 /* 2304 /*
2308 * Eventually check for other socket options to change from 2305 * Eventually check for other socket options to change from
2309 * the default. sock_setsockopt not used because it expects 2306 * the default. sock_setsockopt not used because it expects
2310 * user space buffer 2307 * user space buffer
2311 */ 2308 */
2312 socket->sk->sk_rcvtimeo = 7 * HZ; 2309 socket->sk->sk_rcvtimeo = 7 * HZ;
2313 socket->sk->sk_sndtimeo = 5 * HZ; 2310 socket->sk->sk_sndtimeo = 5 * HZ;
2314 2311
2315 /* make the bufsizes depend on wsize/rsize and max requests */ 2312 /* make the bufsizes depend on wsize/rsize and max requests */
2316 if (server->noautotune) { 2313 if (server->noautotune) {
2317 if (socket->sk->sk_sndbuf < (200 * 1024)) 2314 if (socket->sk->sk_sndbuf < (200 * 1024))
2318 socket->sk->sk_sndbuf = 200 * 1024; 2315 socket->sk->sk_sndbuf = 200 * 1024;
2319 if (socket->sk->sk_rcvbuf < (140 * 1024)) 2316 if (socket->sk->sk_rcvbuf < (140 * 1024))
2320 socket->sk->sk_rcvbuf = 140 * 1024; 2317 socket->sk->sk_rcvbuf = 140 * 1024;
2321 } 2318 }
2322 2319
2323 if (server->tcp_nodelay) { 2320 if (server->tcp_nodelay) {
2324 int val = 1; 2321 int val = 1;
2325 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, 2322 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2326 (char *)&val, sizeof(val)); 2323 (char *)&val, sizeof(val));
2327 if (rc) 2324 if (rc)
2328 cFYI(1, "set TCP_NODELAY socket option error %d", rc); 2325 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2329 } 2326 }
2330 2327
2331 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx", 2328 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
2332 socket->sk->sk_sndbuf, 2329 socket->sk->sk_sndbuf,
2333 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); 2330 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2334 2331
2335 if (sport == htons(RFC1001_PORT)) 2332 if (sport == htons(RFC1001_PORT))
2336 rc = ip_rfc1001_connect(server); 2333 rc = ip_rfc1001_connect(server);
2337 2334
2338 return rc; 2335 return rc;
2339 } 2336 }
2340 2337
2341 static int 2338 static int
2342 ip_connect(struct TCP_Server_Info *server) 2339 ip_connect(struct TCP_Server_Info *server)
2343 { 2340 {
2344 unsigned short int *sport; 2341 unsigned short int *sport;
2345 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; 2342 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2346 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; 2343 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2347 2344
2348 if (server->dstaddr.ss_family == AF_INET6) 2345 if (server->dstaddr.ss_family == AF_INET6)
2349 sport = &addr6->sin6_port; 2346 sport = &addr6->sin6_port;
2350 else 2347 else
2351 sport = &addr->sin_port; 2348 sport = &addr->sin_port;
2352 2349
2353 if (*sport == 0) { 2350 if (*sport == 0) {
2354 int rc; 2351 int rc;
2355 2352
2356 /* try with 445 port at first */ 2353 /* try with 445 port at first */
2357 *sport = htons(CIFS_PORT); 2354 *sport = htons(CIFS_PORT);
2358 2355
2359 rc = generic_ip_connect(server); 2356 rc = generic_ip_connect(server);
2360 if (rc >= 0) 2357 if (rc >= 0)
2361 return rc; 2358 return rc;
2362 2359
2363 /* if it failed, try with 139 port */ 2360 /* if it failed, try with 139 port */
2364 *sport = htons(RFC1001_PORT); 2361 *sport = htons(RFC1001_PORT);
2365 } 2362 }
2366 2363
2367 return generic_ip_connect(server); 2364 return generic_ip_connect(server);
2368 } 2365 }
2369 2366
2370 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 2367 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2371 struct super_block *sb, struct smb_vol *vol_info) 2368 struct super_block *sb, struct smb_vol *vol_info)
2372 { 2369 {
2373 /* if we are reconnecting then should we check to see if 2370 /* if we are reconnecting then should we check to see if
2374 * any requested capabilities changed locally e.g. via 2371 * any requested capabilities changed locally e.g. via
2375 * remount but we can not do much about it here 2372 * remount but we can not do much about it here
2376 * if they have (even if we could detect it by the following) 2373 * if they have (even if we could detect it by the following)
2377 * Perhaps we could add a backpointer to array of sb from tcon 2374 * Perhaps we could add a backpointer to array of sb from tcon
2378 * or if we change to make all sb to same share the same 2375 * or if we change to make all sb to same share the same
2379 * sb as NFS - then we only have one backpointer to sb. 2376 * sb as NFS - then we only have one backpointer to sb.
2380 * What if we wanted to mount the server share twice once with 2377 * What if we wanted to mount the server share twice once with
2381 * and once without posixacls or posix paths? */ 2378 * and once without posixacls or posix paths? */
2382 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 2379 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2383 2380
2384 if (vol_info && vol_info->no_linux_ext) { 2381 if (vol_info && vol_info->no_linux_ext) {
2385 tcon->fsUnixInfo.Capability = 0; 2382 tcon->fsUnixInfo.Capability = 0;
2386 tcon->unix_ext = 0; /* Unix Extensions disabled */ 2383 tcon->unix_ext = 0; /* Unix Extensions disabled */
2387 cFYI(1, "Linux protocol extensions disabled"); 2384 cFYI(1, "Linux protocol extensions disabled");
2388 return; 2385 return;
2389 } else if (vol_info) 2386 } else if (vol_info)
2390 tcon->unix_ext = 1; /* Unix Extensions supported */ 2387 tcon->unix_ext = 1; /* Unix Extensions supported */
2391 2388
2392 if (tcon->unix_ext == 0) { 2389 if (tcon->unix_ext == 0) {
2393 cFYI(1, "Unix extensions disabled so not set on reconnect"); 2390 cFYI(1, "Unix extensions disabled so not set on reconnect");
2394 return; 2391 return;
2395 } 2392 }
2396 2393
2397 if (!CIFSSMBQFSUnixInfo(xid, tcon)) { 2394 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
2398 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 2395 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2399 2396
2400 /* check for reconnect case in which we do not 2397 /* check for reconnect case in which we do not
2401 want to change the mount behavior if we can avoid it */ 2398 want to change the mount behavior if we can avoid it */
2402 if (vol_info == NULL) { 2399 if (vol_info == NULL) {
2403 /* turn off POSIX ACL and PATHNAMES if not set 2400 /* turn off POSIX ACL and PATHNAMES if not set
2404 originally at mount time */ 2401 originally at mount time */
2405 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) 2402 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2406 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 2403 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2407 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { 2404 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2408 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) 2405 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2409 cERROR(1, "POSIXPATH support change"); 2406 cERROR(1, "POSIXPATH support change");
2410 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 2407 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2411 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { 2408 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2412 cERROR(1, "possible reconnect error"); 2409 cERROR(1, "possible reconnect error");
2413 cERROR(1, "server disabled POSIX path support"); 2410 cERROR(1, "server disabled POSIX path support");
2414 } 2411 }
2415 } 2412 }
2416 2413
2417 cap &= CIFS_UNIX_CAP_MASK; 2414 cap &= CIFS_UNIX_CAP_MASK;
2418 if (vol_info && vol_info->no_psx_acl) 2415 if (vol_info && vol_info->no_psx_acl)
2419 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 2416 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2420 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { 2417 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2421 cFYI(1, "negotiated posix acl support"); 2418 cFYI(1, "negotiated posix acl support");
2422 if (sb) 2419 if (sb)
2423 sb->s_flags |= MS_POSIXACL; 2420 sb->s_flags |= MS_POSIXACL;
2424 } 2421 }
2425 2422
2426 if (vol_info && vol_info->posix_paths == 0) 2423 if (vol_info && vol_info->posix_paths == 0)
2427 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 2424 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2428 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 2425 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2429 cFYI(1, "negotiate posix pathnames"); 2426 cFYI(1, "negotiate posix pathnames");
2430 if (sb) 2427 if (sb)
2431 CIFS_SB(sb)->mnt_cifs_flags |= 2428 CIFS_SB(sb)->mnt_cifs_flags |=
2432 CIFS_MOUNT_POSIX_PATHS; 2429 CIFS_MOUNT_POSIX_PATHS;
2433 } 2430 }
2434 2431
2435 /* We might be setting the path sep back to a different 2432 /* We might be setting the path sep back to a different
2436 form if we are reconnecting and the server switched its 2433 form if we are reconnecting and the server switched its
2437 posix path capability for this share */ 2434 posix path capability for this share */
2438 if (sb && (CIFS_SB(sb)->prepathlen > 0)) 2435 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2439 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb)); 2436 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2440 2437
2441 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { 2438 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2442 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { 2439 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2443 CIFS_SB(sb)->rsize = 127 * 1024; 2440 CIFS_SB(sb)->rsize = 127 * 1024;
2444 cFYI(DBG2, "larger reads not supported by srv"); 2441 cFYI(DBG2, "larger reads not supported by srv");
2445 } 2442 }
2446 } 2443 }
2447 2444
2448 2445
2449 cFYI(1, "Negotiate caps 0x%x", (int)cap); 2446 cFYI(1, "Negotiate caps 0x%x", (int)cap);
2450 #ifdef CONFIG_CIFS_DEBUG2 2447 #ifdef CONFIG_CIFS_DEBUG2
2451 if (cap & CIFS_UNIX_FCNTL_CAP) 2448 if (cap & CIFS_UNIX_FCNTL_CAP)
2452 cFYI(1, "FCNTL cap"); 2449 cFYI(1, "FCNTL cap");
2453 if (cap & CIFS_UNIX_EXTATTR_CAP) 2450 if (cap & CIFS_UNIX_EXTATTR_CAP)
2454 cFYI(1, "EXTATTR cap"); 2451 cFYI(1, "EXTATTR cap");
2455 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) 2452 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2456 cFYI(1, "POSIX path cap"); 2453 cFYI(1, "POSIX path cap");
2457 if (cap & CIFS_UNIX_XATTR_CAP) 2454 if (cap & CIFS_UNIX_XATTR_CAP)
2458 cFYI(1, "XATTR cap"); 2455 cFYI(1, "XATTR cap");
2459 if (cap & CIFS_UNIX_POSIX_ACL_CAP) 2456 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
2460 cFYI(1, "POSIX ACL cap"); 2457 cFYI(1, "POSIX ACL cap");
2461 if (cap & CIFS_UNIX_LARGE_READ_CAP) 2458 if (cap & CIFS_UNIX_LARGE_READ_CAP)
2462 cFYI(1, "very large read cap"); 2459 cFYI(1, "very large read cap");
2463 if (cap & CIFS_UNIX_LARGE_WRITE_CAP) 2460 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2464 cFYI(1, "very large write cap"); 2461 cFYI(1, "very large write cap");
2465 #endif /* CIFS_DEBUG2 */ 2462 #endif /* CIFS_DEBUG2 */
2466 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { 2463 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2467 if (vol_info == NULL) { 2464 if (vol_info == NULL) {
2468 cFYI(1, "resetting capabilities failed"); 2465 cFYI(1, "resetting capabilities failed");
2469 } else 2466 } else
2470 cERROR(1, "Negotiating Unix capabilities " 2467 cERROR(1, "Negotiating Unix capabilities "
2471 "with the server failed. Consider " 2468 "with the server failed. Consider "
2472 "mounting with the Unix Extensions\n" 2469 "mounting with the Unix Extensions\n"
2473 "disabled, if problems are found, " 2470 "disabled, if problems are found, "
2474 "by specifying the nounix mount " 2471 "by specifying the nounix mount "
2475 "option."); 2472 "option.");
2476 2473
2477 } 2474 }
2478 } 2475 }
2479 } 2476 }
2480 2477
2481 static void 2478 static void
2482 convert_delimiter(char *path, char delim) 2479 convert_delimiter(char *path, char delim)
2483 { 2480 {
2484 int i; 2481 int i;
2485 char old_delim; 2482 char old_delim;
2486 2483
2487 if (path == NULL) 2484 if (path == NULL)
2488 return; 2485 return;
2489 2486
2490 if (delim == '/') 2487 if (delim == '/')
2491 old_delim = '\\'; 2488 old_delim = '\\';
2492 else 2489 else
2493 old_delim = '/'; 2490 old_delim = '/';
2494 2491
2495 for (i = 0; path[i] != '\0'; i++) { 2492 for (i = 0; path[i] != '\0'; i++) {
2496 if (path[i] == old_delim) 2493 if (path[i] == old_delim)
2497 path[i] = delim; 2494 path[i] = delim;
2498 } 2495 }
2499 } 2496 }
2500 2497
2501 static void setup_cifs_sb(struct smb_vol *pvolume_info, 2498 static void setup_cifs_sb(struct smb_vol *pvolume_info,
2502 struct cifs_sb_info *cifs_sb) 2499 struct cifs_sb_info *cifs_sb)
2503 { 2500 {
2504 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); 2501 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2505 2502
2506 if (pvolume_info->rsize > CIFSMaxBufSize) { 2503 if (pvolume_info->rsize > CIFSMaxBufSize) {
2507 cERROR(1, "rsize %d too large, using MaxBufSize", 2504 cERROR(1, "rsize %d too large, using MaxBufSize",
2508 pvolume_info->rsize); 2505 pvolume_info->rsize);
2509 cifs_sb->rsize = CIFSMaxBufSize; 2506 cifs_sb->rsize = CIFSMaxBufSize;
2510 } else if ((pvolume_info->rsize) && 2507 } else if ((pvolume_info->rsize) &&
2511 (pvolume_info->rsize <= CIFSMaxBufSize)) 2508 (pvolume_info->rsize <= CIFSMaxBufSize))
2512 cifs_sb->rsize = pvolume_info->rsize; 2509 cifs_sb->rsize = pvolume_info->rsize;
2513 else /* default */ 2510 else /* default */
2514 cifs_sb->rsize = CIFSMaxBufSize; 2511 cifs_sb->rsize = CIFSMaxBufSize;
2515 2512
2516 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { 2513 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2517 cERROR(1, "wsize %d too large, using 4096 instead", 2514 cERROR(1, "wsize %d too large, using 4096 instead",
2518 pvolume_info->wsize); 2515 pvolume_info->wsize);
2519 cifs_sb->wsize = 4096; 2516 cifs_sb->wsize = 4096;
2520 } else if (pvolume_info->wsize) 2517 } else if (pvolume_info->wsize)
2521 cifs_sb->wsize = pvolume_info->wsize; 2518 cifs_sb->wsize = pvolume_info->wsize;
2522 else 2519 else
2523 cifs_sb->wsize = min_t(const int, 2520 cifs_sb->wsize = min_t(const int,
2524 PAGEVEC_SIZE * PAGE_CACHE_SIZE, 2521 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2525 127*1024); 2522 127*1024);
2526 /* old default of CIFSMaxBufSize was too small now 2523 /* old default of CIFSMaxBufSize was too small now
2527 that SMB Write2 can send multiple pages in kvec. 2524 that SMB Write2 can send multiple pages in kvec.
2528 RFC1001 does not describe what happens when frame 2525 RFC1001 does not describe what happens when frame
2529 bigger than 128K is sent so use that as max in 2526 bigger than 128K is sent so use that as max in
2530 conjunction with 52K kvec constraint on arch with 4K 2527 conjunction with 52K kvec constraint on arch with 4K
2531 page size */ 2528 page size */
2532 2529
2533 if (cifs_sb->rsize < 2048) { 2530 if (cifs_sb->rsize < 2048) {
2534 cifs_sb->rsize = 2048; 2531 cifs_sb->rsize = 2048;
2535 /* Windows ME may prefer this */ 2532 /* Windows ME may prefer this */
2536 cFYI(1, "readsize set to minimum: 2048"); 2533 cFYI(1, "readsize set to minimum: 2048");
2537 } 2534 }
2538 /* calculate prepath */ 2535 /* calculate prepath */
2539 cifs_sb->prepath = pvolume_info->prepath; 2536 cifs_sb->prepath = pvolume_info->prepath;
2540 if (cifs_sb->prepath) { 2537 if (cifs_sb->prepath) {
2541 cifs_sb->prepathlen = strlen(cifs_sb->prepath); 2538 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2542 /* we can not convert the / to \ in the path 2539 /* we can not convert the / to \ in the path
2543 separators in the prefixpath yet because we do not 2540 separators in the prefixpath yet because we do not
2544 know (until reset_cifs_unix_caps is called later) 2541 know (until reset_cifs_unix_caps is called later)
2545 whether POSIX PATH CAP is available. We normalize 2542 whether POSIX PATH CAP is available. We normalize
2546 the / to \ after reset_cifs_unix_caps is called */ 2543 the / to \ after reset_cifs_unix_caps is called */
2547 pvolume_info->prepath = NULL; 2544 pvolume_info->prepath = NULL;
2548 } else 2545 } else
2549 cifs_sb->prepathlen = 0; 2546 cifs_sb->prepathlen = 0;
2550 cifs_sb->mnt_uid = pvolume_info->linux_uid; 2547 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2551 cifs_sb->mnt_gid = pvolume_info->linux_gid; 2548 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2552 cifs_sb->mnt_file_mode = pvolume_info->file_mode; 2549 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2553 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; 2550 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2554 cFYI(1, "file mode: 0x%x dir mode: 0x%x", 2551 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2555 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); 2552 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2556 2553
2557 cifs_sb->actimeo = pvolume_info->actimeo; 2554 cifs_sb->actimeo = pvolume_info->actimeo;
2558 2555
2559 if (pvolume_info->noperm) 2556 if (pvolume_info->noperm)
2560 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 2557 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2561 if (pvolume_info->setuids) 2558 if (pvolume_info->setuids)
2562 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; 2559 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2563 if (pvolume_info->server_ino) 2560 if (pvolume_info->server_ino)
2564 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; 2561 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2565 if (pvolume_info->remap) 2562 if (pvolume_info->remap)
2566 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; 2563 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2567 if (pvolume_info->no_xattr) 2564 if (pvolume_info->no_xattr)
2568 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; 2565 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2569 if (pvolume_info->sfu_emul) 2566 if (pvolume_info->sfu_emul)
2570 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; 2567 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2571 if (pvolume_info->nobrl) 2568 if (pvolume_info->nobrl)
2572 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; 2569 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2573 if (pvolume_info->nostrictsync) 2570 if (pvolume_info->nostrictsync)
2574 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; 2571 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2575 if (pvolume_info->mand_lock) 2572 if (pvolume_info->mand_lock)
2576 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; 2573 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2577 if (pvolume_info->cifs_acl) 2574 if (pvolume_info->cifs_acl)
2578 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 2575 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2579 if (pvolume_info->override_uid) 2576 if (pvolume_info->override_uid)
2580 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; 2577 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2581 if (pvolume_info->override_gid) 2578 if (pvolume_info->override_gid)
2582 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; 2579 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2583 if (pvolume_info->dynperm) 2580 if (pvolume_info->dynperm)
2584 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; 2581 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2585 if (pvolume_info->fsc) 2582 if (pvolume_info->fsc)
2586 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; 2583 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2587 if (pvolume_info->multiuser) 2584 if (pvolume_info->multiuser)
2588 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | 2585 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
2589 CIFS_MOUNT_NO_PERM); 2586 CIFS_MOUNT_NO_PERM);
2590 if (pvolume_info->strict_io) 2587 if (pvolume_info->strict_io)
2591 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO; 2588 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
2592 if (pvolume_info->direct_io) { 2589 if (pvolume_info->direct_io) {
2593 cFYI(1, "mounting share using direct i/o"); 2590 cFYI(1, "mounting share using direct i/o");
2594 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2591 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2595 } 2592 }
2596 if (pvolume_info->mfsymlinks) { 2593 if (pvolume_info->mfsymlinks) {
2597 if (pvolume_info->sfu_emul) { 2594 if (pvolume_info->sfu_emul) {
2598 cERROR(1, "mount option mfsymlinks ignored if sfu " 2595 cERROR(1, "mount option mfsymlinks ignored if sfu "
2599 "mount option is used"); 2596 "mount option is used");
2600 } else { 2597 } else {
2601 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; 2598 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2602 } 2599 }
2603 } 2600 }
2604 2601
2605 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) 2602 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2606 cERROR(1, "mount option dynperm ignored if cifsacl " 2603 cERROR(1, "mount option dynperm ignored if cifsacl "
2607 "mount option supported"); 2604 "mount option supported");
2608 } 2605 }
2609 2606
2610 static int 2607 static int
2611 is_path_accessible(int xid, struct cifsTconInfo *tcon, 2608 is_path_accessible(int xid, struct cifsTconInfo *tcon,
2612 struct cifs_sb_info *cifs_sb, const char *full_path) 2609 struct cifs_sb_info *cifs_sb, const char *full_path)
2613 { 2610 {
2614 int rc; 2611 int rc;
2615 FILE_ALL_INFO *pfile_info; 2612 FILE_ALL_INFO *pfile_info;
2616 2613
2617 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 2614 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2618 if (pfile_info == NULL) 2615 if (pfile_info == NULL)
2619 return -ENOMEM; 2616 return -ENOMEM;
2620 2617
2621 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, 2618 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2622 0 /* not legacy */, cifs_sb->local_nls, 2619 0 /* not legacy */, cifs_sb->local_nls,
2623 cifs_sb->mnt_cifs_flags & 2620 cifs_sb->mnt_cifs_flags &
2624 CIFS_MOUNT_MAP_SPECIAL_CHR); 2621 CIFS_MOUNT_MAP_SPECIAL_CHR);
2625 kfree(pfile_info); 2622 kfree(pfile_info);
2626 return rc; 2623 return rc;
2627 } 2624 }
2628 2625
2629 static void 2626 static void
2630 cleanup_volume_info(struct smb_vol **pvolume_info) 2627 cleanup_volume_info(struct smb_vol **pvolume_info)
2631 { 2628 {
2632 struct smb_vol *volume_info; 2629 struct smb_vol *volume_info;
2633 2630
2634 if (!pvolume_info || !*pvolume_info) 2631 if (!pvolume_info || !*pvolume_info)
2635 return; 2632 return;
2636 2633
2637 volume_info = *pvolume_info; 2634 volume_info = *pvolume_info;
2638 kzfree(volume_info->password); 2635 kzfree(volume_info->password);
2639 kfree(volume_info->UNC); 2636 kfree(volume_info->UNC);
2640 kfree(volume_info->prepath); 2637 kfree(volume_info->prepath);
2641 kfree(volume_info); 2638 kfree(volume_info);
2642 *pvolume_info = NULL; 2639 *pvolume_info = NULL;
2643 return; 2640 return;
2644 } 2641 }
2645 2642
2646 #ifdef CONFIG_CIFS_DFS_UPCALL 2643 #ifdef CONFIG_CIFS_DFS_UPCALL
2647 /* build_path_to_root returns full path to root when 2644 /* build_path_to_root returns full path to root when
2648 * we do not have an exiting connection (tcon) */ 2645 * we do not have an exiting connection (tcon) */
2649 static char * 2646 static char *
2650 build_unc_path_to_root(const struct smb_vol *volume_info, 2647 build_unc_path_to_root(const struct smb_vol *volume_info,
2651 const struct cifs_sb_info *cifs_sb) 2648 const struct cifs_sb_info *cifs_sb)
2652 { 2649 {
2653 char *full_path; 2650 char *full_path;
2654 2651
2655 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); 2652 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2656 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL); 2653 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2657 if (full_path == NULL) 2654 if (full_path == NULL)
2658 return ERR_PTR(-ENOMEM); 2655 return ERR_PTR(-ENOMEM);
2659 2656
2660 strncpy(full_path, volume_info->UNC, unc_len); 2657 strncpy(full_path, volume_info->UNC, unc_len);
2661 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { 2658 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2662 int i; 2659 int i;
2663 for (i = 0; i < unc_len; i++) { 2660 for (i = 0; i < unc_len; i++) {
2664 if (full_path[i] == '\\') 2661 if (full_path[i] == '\\')
2665 full_path[i] = '/'; 2662 full_path[i] = '/';
2666 } 2663 }
2667 } 2664 }
2668 2665
2669 if (cifs_sb->prepathlen) 2666 if (cifs_sb->prepathlen)
2670 strncpy(full_path + unc_len, cifs_sb->prepath, 2667 strncpy(full_path + unc_len, cifs_sb->prepath,
2671 cifs_sb->prepathlen); 2668 cifs_sb->prepathlen);
2672 2669
2673 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */ 2670 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2674 return full_path; 2671 return full_path;
2675 } 2672 }
2676 #endif 2673 #endif
2677 2674
2678 int 2675 int
2679 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 2676 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2680 char *mount_data_global, const char *devname) 2677 char *mount_data_global, const char *devname)
2681 { 2678 {
2682 int rc; 2679 int rc;
2683 int xid; 2680 int xid;
2684 struct smb_vol *volume_info; 2681 struct smb_vol *volume_info;
2685 struct cifsSesInfo *pSesInfo; 2682 struct cifsSesInfo *pSesInfo;
2686 struct cifsTconInfo *tcon; 2683 struct cifsTconInfo *tcon;
2687 struct TCP_Server_Info *srvTcp; 2684 struct TCP_Server_Info *srvTcp;
2688 char *full_path; 2685 char *full_path;
2689 char *mount_data = mount_data_global; 2686 char *mount_data = mount_data_global;
2690 struct tcon_link *tlink; 2687 struct tcon_link *tlink;
2691 #ifdef CONFIG_CIFS_DFS_UPCALL 2688 #ifdef CONFIG_CIFS_DFS_UPCALL
2692 struct dfs_info3_param *referrals = NULL; 2689 struct dfs_info3_param *referrals = NULL;
2693 unsigned int num_referrals = 0; 2690 unsigned int num_referrals = 0;
2694 int referral_walks_count = 0; 2691 int referral_walks_count = 0;
2695 try_mount_again: 2692 try_mount_again:
2696 #endif 2693 #endif
2697 rc = 0; 2694 rc = 0;
2698 tcon = NULL; 2695 tcon = NULL;
2699 pSesInfo = NULL; 2696 pSesInfo = NULL;
2700 srvTcp = NULL; 2697 srvTcp = NULL;
2701 full_path = NULL; 2698 full_path = NULL;
2702 tlink = NULL; 2699 tlink = NULL;
2703 2700
2704 xid = GetXid(); 2701 xid = GetXid();
2705 2702
2706 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); 2703 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2707 if (!volume_info) { 2704 if (!volume_info) {
2708 rc = -ENOMEM; 2705 rc = -ENOMEM;
2709 goto out; 2706 goto out;
2710 } 2707 }
2711 2708
2712 if (cifs_parse_mount_options(mount_data, devname, volume_info)) { 2709 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2713 rc = -EINVAL; 2710 rc = -EINVAL;
2714 goto out; 2711 goto out;
2715 } 2712 }
2716 2713
2717 if (volume_info->nullauth) { 2714 if (volume_info->nullauth) {
2718 cFYI(1, "null user"); 2715 cFYI(1, "null user");
2719 volume_info->username = ""; 2716 volume_info->username = "";
2720 } else if (volume_info->username) { 2717 } else if (volume_info->username) {
2721 /* BB fixme parse for domain name here */ 2718 /* BB fixme parse for domain name here */
2722 cFYI(1, "Username: %s", volume_info->username); 2719 cFYI(1, "Username: %s", volume_info->username);
2723 } else { 2720 } else {
2724 cifserror("No username specified"); 2721 cifserror("No username specified");
2725 /* In userspace mount helper we can get user name from alternate 2722 /* In userspace mount helper we can get user name from alternate
2726 locations such as env variables and files on disk */ 2723 locations such as env variables and files on disk */
2727 rc = -EINVAL; 2724 rc = -EINVAL;
2728 goto out; 2725 goto out;
2729 } 2726 }
2730 2727
2731 /* this is needed for ASCII cp to Unicode converts */ 2728 /* this is needed for ASCII cp to Unicode converts */
2732 if (volume_info->iocharset == NULL) { 2729 if (volume_info->iocharset == NULL) {
2733 /* load_nls_default cannot return null */ 2730 /* load_nls_default cannot return null */
2734 volume_info->local_nls = load_nls_default(); 2731 volume_info->local_nls = load_nls_default();
2735 } else { 2732 } else {
2736 volume_info->local_nls = load_nls(volume_info->iocharset); 2733 volume_info->local_nls = load_nls(volume_info->iocharset);
2737 if (volume_info->local_nls == NULL) { 2734 if (volume_info->local_nls == NULL) {
2738 cERROR(1, "CIFS mount error: iocharset %s not found", 2735 cERROR(1, "CIFS mount error: iocharset %s not found",
2739 volume_info->iocharset); 2736 volume_info->iocharset);
2740 rc = -ELIBACC; 2737 rc = -ELIBACC;
2741 goto out; 2738 goto out;
2742 } 2739 }
2743 } 2740 }
2744 cifs_sb->local_nls = volume_info->local_nls; 2741 cifs_sb->local_nls = volume_info->local_nls;
2745 2742
2746 /* get a reference to a tcp session */ 2743 /* get a reference to a tcp session */
2747 srvTcp = cifs_get_tcp_session(volume_info); 2744 srvTcp = cifs_get_tcp_session(volume_info);
2748 if (IS_ERR(srvTcp)) { 2745 if (IS_ERR(srvTcp)) {
2749 rc = PTR_ERR(srvTcp); 2746 rc = PTR_ERR(srvTcp);
2750 goto out; 2747 goto out;
2751 } 2748 }
2752 2749
2753 /* get a reference to a SMB session */ 2750 /* get a reference to a SMB session */
2754 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info); 2751 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2755 if (IS_ERR(pSesInfo)) { 2752 if (IS_ERR(pSesInfo)) {
2756 rc = PTR_ERR(pSesInfo); 2753 rc = PTR_ERR(pSesInfo);
2757 pSesInfo = NULL; 2754 pSesInfo = NULL;
2758 goto mount_fail_check; 2755 goto mount_fail_check;
2759 } 2756 }
2760 2757
2761 setup_cifs_sb(volume_info, cifs_sb); 2758 setup_cifs_sb(volume_info, cifs_sb);
2762 if (pSesInfo->capabilities & CAP_LARGE_FILES) 2759 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2763 sb->s_maxbytes = MAX_LFS_FILESIZE; 2760 sb->s_maxbytes = MAX_LFS_FILESIZE;
2764 else 2761 else
2765 sb->s_maxbytes = MAX_NON_LFS; 2762 sb->s_maxbytes = MAX_NON_LFS;
2766 2763
2767 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 2764 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2768 sb->s_time_gran = 100; 2765 sb->s_time_gran = 100;
2769 2766
2770 /* search for existing tcon to this server share */ 2767 /* search for existing tcon to this server share */
2771 tcon = cifs_get_tcon(pSesInfo, volume_info); 2768 tcon = cifs_get_tcon(pSesInfo, volume_info);
2772 if (IS_ERR(tcon)) { 2769 if (IS_ERR(tcon)) {
2773 rc = PTR_ERR(tcon); 2770 rc = PTR_ERR(tcon);
2774 tcon = NULL; 2771 tcon = NULL;
2775 goto remote_path_check; 2772 goto remote_path_check;
2776 } 2773 }
2777 2774
2778 /* do not care if following two calls succeed - informational */ 2775 /* do not care if following two calls succeed - informational */
2779 if (!tcon->ipc) { 2776 if (!tcon->ipc) {
2780 CIFSSMBQFSDeviceInfo(xid, tcon); 2777 CIFSSMBQFSDeviceInfo(xid, tcon);
2781 CIFSSMBQFSAttributeInfo(xid, tcon); 2778 CIFSSMBQFSAttributeInfo(xid, tcon);
2782 } 2779 }
2783 2780
2784 /* tell server which Unix caps we support */ 2781 /* tell server which Unix caps we support */
2785 if (tcon->ses->capabilities & CAP_UNIX) 2782 if (tcon->ses->capabilities & CAP_UNIX)
2786 /* reset of caps checks mount to see if unix extensions 2783 /* reset of caps checks mount to see if unix extensions
2787 disabled for just this mount */ 2784 disabled for just this mount */
2788 reset_cifs_unix_caps(xid, tcon, sb, volume_info); 2785 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2789 else 2786 else
2790 tcon->unix_ext = 0; /* server does not support them */ 2787 tcon->unix_ext = 0; /* server does not support them */
2791 2788
2792 /* convert forward to back slashes in prepath here if needed */ 2789 /* convert forward to back slashes in prepath here if needed */
2793 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) 2790 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2794 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); 2791 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2795 2792
2796 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { 2793 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2797 cifs_sb->rsize = 1024 * 127; 2794 cifs_sb->rsize = 1024 * 127;
2798 cFYI(DBG2, "no very large read support, rsize now 127K"); 2795 cFYI(DBG2, "no very large read support, rsize now 127K");
2799 } 2796 }
2800 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) 2797 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2801 cifs_sb->wsize = min(cifs_sb->wsize, 2798 cifs_sb->wsize = min(cifs_sb->wsize,
2802 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); 2799 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2803 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X)) 2800 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2804 cifs_sb->rsize = min(cifs_sb->rsize, 2801 cifs_sb->rsize = min(cifs_sb->rsize,
2805 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); 2802 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2806 2803
2807 remote_path_check: 2804 remote_path_check:
2808 /* check if a whole path (including prepath) is not remote */ 2805 /* check if a whole path (including prepath) is not remote */
2809 if (!rc && cifs_sb->prepathlen && tcon) { 2806 if (!rc && cifs_sb->prepathlen && tcon) {
2810 /* build_path_to_root works only when we have a valid tcon */ 2807 /* build_path_to_root works only when we have a valid tcon */
2811 full_path = cifs_build_path_to_root(cifs_sb, tcon); 2808 full_path = cifs_build_path_to_root(cifs_sb, tcon);
2812 if (full_path == NULL) { 2809 if (full_path == NULL) {
2813 rc = -ENOMEM; 2810 rc = -ENOMEM;
2814 goto mount_fail_check; 2811 goto mount_fail_check;
2815 } 2812 }
2816 rc = is_path_accessible(xid, tcon, cifs_sb, full_path); 2813 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
2817 if (rc != 0 && rc != -EREMOTE) { 2814 if (rc != 0 && rc != -EREMOTE) {
2818 kfree(full_path); 2815 kfree(full_path);
2819 goto mount_fail_check; 2816 goto mount_fail_check;
2820 } 2817 }
2821 kfree(full_path); 2818 kfree(full_path);
2822 } 2819 }
2823 2820
2824 /* get referral if needed */ 2821 /* get referral if needed */
2825 if (rc == -EREMOTE) { 2822 if (rc == -EREMOTE) {
2826 #ifdef CONFIG_CIFS_DFS_UPCALL 2823 #ifdef CONFIG_CIFS_DFS_UPCALL
2827 if (referral_walks_count > MAX_NESTED_LINKS) { 2824 if (referral_walks_count > MAX_NESTED_LINKS) {
2828 /* 2825 /*
2829 * BB: when we implement proper loop detection, 2826 * BB: when we implement proper loop detection,
2830 * we will remove this check. But now we need it 2827 * we will remove this check. But now we need it
2831 * to prevent an indefinite loop if 'DFS tree' is 2828 * to prevent an indefinite loop if 'DFS tree' is
2832 * misconfigured (i.e. has loops). 2829 * misconfigured (i.e. has loops).
2833 */ 2830 */
2834 rc = -ELOOP; 2831 rc = -ELOOP;
2835 goto mount_fail_check; 2832 goto mount_fail_check;
2836 } 2833 }
2837 /* convert forward to back slashes in prepath here if needed */ 2834 /* convert forward to back slashes in prepath here if needed */
2838 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) 2835 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2839 convert_delimiter(cifs_sb->prepath, 2836 convert_delimiter(cifs_sb->prepath,
2840 CIFS_DIR_SEP(cifs_sb)); 2837 CIFS_DIR_SEP(cifs_sb));
2841 full_path = build_unc_path_to_root(volume_info, cifs_sb); 2838 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2842 if (IS_ERR(full_path)) { 2839 if (IS_ERR(full_path)) {
2843 rc = PTR_ERR(full_path); 2840 rc = PTR_ERR(full_path);
2844 goto mount_fail_check; 2841 goto mount_fail_check;
2845 } 2842 }
2846 2843
2847 cFYI(1, "Getting referral for: %s", full_path); 2844 cFYI(1, "Getting referral for: %s", full_path);
2848 rc = get_dfs_path(xid, pSesInfo , full_path + 1, 2845 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2849 cifs_sb->local_nls, &num_referrals, &referrals, 2846 cifs_sb->local_nls, &num_referrals, &referrals,
2850 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 2847 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2851 if (!rc && num_referrals > 0) { 2848 if (!rc && num_referrals > 0) {
2852 char *fake_devname = NULL; 2849 char *fake_devname = NULL;
2853 2850
2854 if (mount_data != mount_data_global) 2851 if (mount_data != mount_data_global)
2855 kfree(mount_data); 2852 kfree(mount_data);
2856 2853
2857 mount_data = cifs_compose_mount_options( 2854 mount_data = cifs_compose_mount_options(
2858 cifs_sb->mountdata, full_path + 1, 2855 cifs_sb->mountdata, full_path + 1,
2859 referrals, &fake_devname); 2856 referrals, &fake_devname);
2860 2857
2861 free_dfs_info_array(referrals, num_referrals); 2858 free_dfs_info_array(referrals, num_referrals);
2862 kfree(fake_devname); 2859 kfree(fake_devname);
2863 kfree(full_path); 2860 kfree(full_path);
2864 2861
2865 if (IS_ERR(mount_data)) { 2862 if (IS_ERR(mount_data)) {
2866 rc = PTR_ERR(mount_data); 2863 rc = PTR_ERR(mount_data);
2867 mount_data = NULL; 2864 mount_data = NULL;
2868 goto mount_fail_check; 2865 goto mount_fail_check;
2869 } 2866 }
2870 2867
2871 if (tcon) 2868 if (tcon)
2872 cifs_put_tcon(tcon); 2869 cifs_put_tcon(tcon);
2873 else if (pSesInfo) 2870 else if (pSesInfo)
2874 cifs_put_smb_ses(pSesInfo); 2871 cifs_put_smb_ses(pSesInfo);
2875 2872
2876 cleanup_volume_info(&volume_info); 2873 cleanup_volume_info(&volume_info);
2877 referral_walks_count++; 2874 referral_walks_count++;
2878 FreeXid(xid); 2875 FreeXid(xid);
2879 goto try_mount_again; 2876 goto try_mount_again;
2880 } 2877 }
2881 #else /* No DFS support, return error on mount */ 2878 #else /* No DFS support, return error on mount */
2882 rc = -EOPNOTSUPP; 2879 rc = -EOPNOTSUPP;
2883 #endif 2880 #endif
2884 } 2881 }
2885 2882
2886 if (rc) 2883 if (rc)
2887 goto mount_fail_check; 2884 goto mount_fail_check;
2888 2885
2889 /* now, hang the tcon off of the superblock */ 2886 /* now, hang the tcon off of the superblock */
2890 tlink = kzalloc(sizeof *tlink, GFP_KERNEL); 2887 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2891 if (tlink == NULL) { 2888 if (tlink == NULL) {
2892 rc = -ENOMEM; 2889 rc = -ENOMEM;
2893 goto mount_fail_check; 2890 goto mount_fail_check;
2894 } 2891 }
2895 2892
2896 tlink->tl_uid = pSesInfo->linux_uid; 2893 tlink->tl_uid = pSesInfo->linux_uid;
2897 tlink->tl_tcon = tcon; 2894 tlink->tl_tcon = tcon;
2898 tlink->tl_time = jiffies; 2895 tlink->tl_time = jiffies;
2899 set_bit(TCON_LINK_MASTER, &tlink->tl_flags); 2896 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2900 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); 2897 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2901 2898
2902 cifs_sb->master_tlink = tlink; 2899 cifs_sb->master_tlink = tlink;
2903 spin_lock(&cifs_sb->tlink_tree_lock); 2900 spin_lock(&cifs_sb->tlink_tree_lock);
2904 tlink_rb_insert(&cifs_sb->tlink_tree, tlink); 2901 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
2905 spin_unlock(&cifs_sb->tlink_tree_lock); 2902 spin_unlock(&cifs_sb->tlink_tree_lock);
2906 2903
2907 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, 2904 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
2908 TLINK_IDLE_EXPIRE); 2905 TLINK_IDLE_EXPIRE);
2909 2906
2910 mount_fail_check: 2907 mount_fail_check:
2911 /* on error free sesinfo and tcon struct if needed */ 2908 /* on error free sesinfo and tcon struct if needed */
2912 if (rc) { 2909 if (rc) {
2913 if (mount_data != mount_data_global) 2910 if (mount_data != mount_data_global)
2914 kfree(mount_data); 2911 kfree(mount_data);
2915 /* If find_unc succeeded then rc == 0 so we can not end */ 2912 /* If find_unc succeeded then rc == 0 so we can not end */
2916 /* up accidently freeing someone elses tcon struct */ 2913 /* up accidently freeing someone elses tcon struct */
2917 if (tcon) 2914 if (tcon)
2918 cifs_put_tcon(tcon); 2915 cifs_put_tcon(tcon);
2919 else if (pSesInfo) 2916 else if (pSesInfo)
2920 cifs_put_smb_ses(pSesInfo); 2917 cifs_put_smb_ses(pSesInfo);
2921 else 2918 else
2922 cifs_put_tcp_session(srvTcp); 2919 cifs_put_tcp_session(srvTcp);
2923 goto out; 2920 goto out;
2924 } 2921 }
2925 2922
2926 /* volume_info->password is freed above when existing session found 2923 /* volume_info->password is freed above when existing session found
2927 (in which case it is not needed anymore) but when new sesion is created 2924 (in which case it is not needed anymore) but when new sesion is created
2928 the password ptr is put in the new session structure (in which case the 2925 the password ptr is put in the new session structure (in which case the
2929 password will be freed at unmount time) */ 2926 password will be freed at unmount time) */
2930 out: 2927 out:
2931 /* zero out password before freeing */ 2928 /* zero out password before freeing */
2932 cleanup_volume_info(&volume_info); 2929 cleanup_volume_info(&volume_info);
2933 FreeXid(xid); 2930 FreeXid(xid);
2934 return rc; 2931 return rc;
2935 } 2932 }
2936 2933
2937 int 2934 int
2938 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 2935 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2939 const char *tree, struct cifsTconInfo *tcon, 2936 const char *tree, struct cifsTconInfo *tcon,
2940 const struct nls_table *nls_codepage) 2937 const struct nls_table *nls_codepage)
2941 { 2938 {
2942 struct smb_hdr *smb_buffer; 2939 struct smb_hdr *smb_buffer;
2943 struct smb_hdr *smb_buffer_response; 2940 struct smb_hdr *smb_buffer_response;
2944 TCONX_REQ *pSMB; 2941 TCONX_REQ *pSMB;
2945 TCONX_RSP *pSMBr; 2942 TCONX_RSP *pSMBr;
2946 unsigned char *bcc_ptr; 2943 unsigned char *bcc_ptr;
2947 int rc = 0; 2944 int rc = 0;
2948 int length; 2945 int length;
2949 __u16 bytes_left, count; 2946 __u16 bytes_left, count;
2950 2947
2951 if (ses == NULL) 2948 if (ses == NULL)
2952 return -EIO; 2949 return -EIO;
2953 2950
2954 smb_buffer = cifs_buf_get(); 2951 smb_buffer = cifs_buf_get();
2955 if (smb_buffer == NULL) 2952 if (smb_buffer == NULL)
2956 return -ENOMEM; 2953 return -ENOMEM;
2957 2954
2958 smb_buffer_response = smb_buffer; 2955 smb_buffer_response = smb_buffer;
2959 2956
2960 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, 2957 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
2961 NULL /*no tid */ , 4 /*wct */ ); 2958 NULL /*no tid */ , 4 /*wct */ );
2962 2959
2963 smb_buffer->Mid = GetNextMid(ses->server); 2960 smb_buffer->Mid = GetNextMid(ses->server);
2964 smb_buffer->Uid = ses->Suid; 2961 smb_buffer->Uid = ses->Suid;
2965 pSMB = (TCONX_REQ *) smb_buffer; 2962 pSMB = (TCONX_REQ *) smb_buffer;
2966 pSMBr = (TCONX_RSP *) smb_buffer_response; 2963 pSMBr = (TCONX_RSP *) smb_buffer_response;
2967 2964
2968 pSMB->AndXCommand = 0xFF; 2965 pSMB->AndXCommand = 0xFF;
2969 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); 2966 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
2970 bcc_ptr = &pSMB->Password[0]; 2967 bcc_ptr = &pSMB->Password[0];
2971 if ((ses->server->secMode) & SECMODE_USER) { 2968 if ((ses->server->secMode) & SECMODE_USER) {
2972 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 2969 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
2973 *bcc_ptr = 0; /* password is null byte */ 2970 *bcc_ptr = 0; /* password is null byte */
2974 bcc_ptr++; /* skip password */ 2971 bcc_ptr++; /* skip password */
2975 /* already aligned so no need to do it below */ 2972 /* already aligned so no need to do it below */
2976 } else { 2973 } else {
2977 pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE); 2974 pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
2978 /* BB FIXME add code to fail this if NTLMv2 or Kerberos 2975 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
2979 specified as required (when that support is added to 2976 specified as required (when that support is added to
2980 the vfs in the future) as only NTLM or the much 2977 the vfs in the future) as only NTLM or the much
2981 weaker LANMAN (which we do not send by default) is accepted 2978 weaker LANMAN (which we do not send by default) is accepted
2982 by Samba (not sure whether other servers allow 2979 by Samba (not sure whether other servers allow
2983 NTLMv2 password here) */ 2980 NTLMv2 password here) */
2984 #ifdef CONFIG_CIFS_WEAK_PW_HASH 2981 #ifdef CONFIG_CIFS_WEAK_PW_HASH
2985 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 2982 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2986 (ses->server->secType == LANMAN)) 2983 (ses->server->secType == LANMAN))
2987 calc_lanman_hash(tcon->password, ses->server->cryptkey, 2984 calc_lanman_hash(tcon->password, ses->server->cryptkey,
2988 ses->server->secMode & 2985 ses->server->secMode &
2989 SECMODE_PW_ENCRYPT ? true : false, 2986 SECMODE_PW_ENCRYPT ? true : false,
2990 bcc_ptr); 2987 bcc_ptr);
2991 else 2988 else
2992 #endif /* CIFS_WEAK_PW_HASH */ 2989 #endif /* CIFS_WEAK_PW_HASH */
2993 SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr); 2990 rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
2991 bcc_ptr);
2994 2992
2995 bcc_ptr += CIFS_AUTH_RESP_SIZE; 2993 bcc_ptr += CIFS_AUTH_RESP_SIZE;
2996 if (ses->capabilities & CAP_UNICODE) { 2994 if (ses->capabilities & CAP_UNICODE) {
2997 /* must align unicode strings */ 2995 /* must align unicode strings */
2998 *bcc_ptr = 0; /* null byte password */ 2996 *bcc_ptr = 0; /* null byte password */
2999 bcc_ptr++; 2997 bcc_ptr++;
3000 } 2998 }
3001 } 2999 }
3002 3000
3003 if (ses->server->secMode & 3001 if (ses->server->secMode &
3004 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3002 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3005 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3003 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3006 3004
3007 if (ses->capabilities & CAP_STATUS32) { 3005 if (ses->capabilities & CAP_STATUS32) {
3008 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS; 3006 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3009 } 3007 }
3010 if (ses->capabilities & CAP_DFS) { 3008 if (ses->capabilities & CAP_DFS) {
3011 smb_buffer->Flags2 |= SMBFLG2_DFS; 3009 smb_buffer->Flags2 |= SMBFLG2_DFS;
3012 } 3010 }
3013 if (ses->capabilities & CAP_UNICODE) { 3011 if (ses->capabilities & CAP_UNICODE) {
3014 smb_buffer->Flags2 |= SMBFLG2_UNICODE; 3012 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3015 length = 3013 length =
3016 cifs_strtoUCS((__le16 *) bcc_ptr, tree, 3014 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3017 6 /* max utf8 char length in bytes */ * 3015 6 /* max utf8 char length in bytes */ *
3018 (/* server len*/ + 256 /* share len */), nls_codepage); 3016 (/* server len*/ + 256 /* share len */), nls_codepage);
3019 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */ 3017 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3020 bcc_ptr += 2; /* skip trailing null */ 3018 bcc_ptr += 2; /* skip trailing null */
3021 } else { /* ASCII */ 3019 } else { /* ASCII */
3022 strcpy(bcc_ptr, tree); 3020 strcpy(bcc_ptr, tree);
3023 bcc_ptr += strlen(tree) + 1; 3021 bcc_ptr += strlen(tree) + 1;
3024 } 3022 }
3025 strcpy(bcc_ptr, "?????"); 3023 strcpy(bcc_ptr, "?????");
3026 bcc_ptr += strlen("?????"); 3024 bcc_ptr += strlen("?????");
3027 bcc_ptr += 1; 3025 bcc_ptr += 1;
3028 count = bcc_ptr - &pSMB->Password[0]; 3026 count = bcc_ptr - &pSMB->Password[0];
3029 pSMB->hdr.smb_buf_length += count; 3027 pSMB->hdr.smb_buf_length += count;
3030 pSMB->ByteCount = cpu_to_le16(count); 3028 pSMB->ByteCount = cpu_to_le16(count);
3031 3029
3032 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 3030 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3033 0); 3031 0);
3034 3032
3035 /* above now done in SendReceive */ 3033 /* above now done in SendReceive */
3036 if ((rc == 0) && (tcon != NULL)) { 3034 if ((rc == 0) && (tcon != NULL)) {
3037 bool is_unicode; 3035 bool is_unicode;
3038 3036
3039 tcon->tidStatus = CifsGood; 3037 tcon->tidStatus = CifsGood;
3040 tcon->need_reconnect = false; 3038 tcon->need_reconnect = false;
3041 tcon->tid = smb_buffer_response->Tid; 3039 tcon->tid = smb_buffer_response->Tid;
3042 bcc_ptr = pByteArea(smb_buffer_response); 3040 bcc_ptr = pByteArea(smb_buffer_response);
3043 bytes_left = get_bcc(smb_buffer_response); 3041 bytes_left = get_bcc(smb_buffer_response);
3044 length = strnlen(bcc_ptr, bytes_left - 2); 3042 length = strnlen(bcc_ptr, bytes_left - 2);
3045 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) 3043 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3046 is_unicode = true; 3044 is_unicode = true;
3047 else 3045 else
3048 is_unicode = false; 3046 is_unicode = false;
3049 3047
3050 3048
3051 /* skip service field (NB: this field is always ASCII) */ 3049 /* skip service field (NB: this field is always ASCII) */
3052 if (length == 3) { 3050 if (length == 3) {
3053 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') && 3051 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3054 (bcc_ptr[2] == 'C')) { 3052 (bcc_ptr[2] == 'C')) {
3055 cFYI(1, "IPC connection"); 3053 cFYI(1, "IPC connection");
3056 tcon->ipc = 1; 3054 tcon->ipc = 1;
3057 } 3055 }
3058 } else if (length == 2) { 3056 } else if (length == 2) {
3059 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) { 3057 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3060 /* the most common case */ 3058 /* the most common case */
3061 cFYI(1, "disk share connection"); 3059 cFYI(1, "disk share connection");
3062 } 3060 }
3063 } 3061 }
3064 bcc_ptr += length + 1; 3062 bcc_ptr += length + 1;
3065 bytes_left -= (length + 1); 3063 bytes_left -= (length + 1);
3066 strncpy(tcon->treeName, tree, MAX_TREE_SIZE); 3064 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3067 3065
3068 /* mostly informational -- no need to fail on error here */ 3066 /* mostly informational -- no need to fail on error here */
3069 kfree(tcon->nativeFileSystem); 3067 kfree(tcon->nativeFileSystem);
3070 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr, 3068 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
3071 bytes_left, is_unicode, 3069 bytes_left, is_unicode,
3072 nls_codepage); 3070 nls_codepage);
3073 3071
3074 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem); 3072 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
3075 3073
3076 if ((smb_buffer_response->WordCount == 3) || 3074 if ((smb_buffer_response->WordCount == 3) ||
3077 (smb_buffer_response->WordCount == 7)) 3075 (smb_buffer_response->WordCount == 7))
3078 /* field is in same location */ 3076 /* field is in same location */
3079 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3077 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3080 else 3078 else
3081 tcon->Flags = 0; 3079 tcon->Flags = 0;
3082 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags); 3080 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
3083 } else if ((rc == 0) && tcon == NULL) { 3081 } else if ((rc == 0) && tcon == NULL) {
3084 /* all we need to save for IPC$ connection */ 3082 /* all we need to save for IPC$ connection */
3085 ses->ipc_tid = smb_buffer_response->Tid; 3083 ses->ipc_tid = smb_buffer_response->Tid;
3086 } 3084 }
3087 3085
3088 cifs_buf_release(smb_buffer); 3086 cifs_buf_release(smb_buffer);
3089 return rc; 3087 return rc;
3090 } 3088 }
3091 3089
3092 int 3090 int
3093 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) 3091 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3094 { 3092 {
3095 struct rb_root *root = &cifs_sb->tlink_tree; 3093 struct rb_root *root = &cifs_sb->tlink_tree;
3096 struct rb_node *node; 3094 struct rb_node *node;
3097 struct tcon_link *tlink; 3095 struct tcon_link *tlink;
3098 char *tmp; 3096 char *tmp;
3099 3097
3100 cancel_delayed_work_sync(&cifs_sb->prune_tlinks); 3098 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3101 3099
3102 spin_lock(&cifs_sb->tlink_tree_lock); 3100 spin_lock(&cifs_sb->tlink_tree_lock);
3103 while ((node = rb_first(root))) { 3101 while ((node = rb_first(root))) {
3104 tlink = rb_entry(node, struct tcon_link, tl_rbnode); 3102 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3105 cifs_get_tlink(tlink); 3103 cifs_get_tlink(tlink);
3106 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); 3104 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3107 rb_erase(node, root); 3105 rb_erase(node, root);
3108 3106
3109 spin_unlock(&cifs_sb->tlink_tree_lock); 3107 spin_unlock(&cifs_sb->tlink_tree_lock);
3110 cifs_put_tlink(tlink); 3108 cifs_put_tlink(tlink);
3111 spin_lock(&cifs_sb->tlink_tree_lock); 3109 spin_lock(&cifs_sb->tlink_tree_lock);
3112 } 3110 }
3113 spin_unlock(&cifs_sb->tlink_tree_lock); 3111 spin_unlock(&cifs_sb->tlink_tree_lock);
3114 3112
3115 tmp = cifs_sb->prepath; 3113 tmp = cifs_sb->prepath;
3116 cifs_sb->prepathlen = 0; 3114 cifs_sb->prepathlen = 0;
3117 cifs_sb->prepath = NULL; 3115 cifs_sb->prepath = NULL;
3118 kfree(tmp); 3116 kfree(tmp);
3119 3117
3120 return 0; 3118 return 0;
3121 } 3119 }
3122 3120
3123 int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) 3121 int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
3124 { 3122 {
3125 int rc = 0; 3123 int rc = 0;
3126 struct TCP_Server_Info *server = ses->server; 3124 struct TCP_Server_Info *server = ses->server;
3127 3125
3128 /* only send once per connect */ 3126 /* only send once per connect */
3129 if (server->maxBuf != 0) 3127 if (server->maxBuf != 0)
3130 return 0; 3128 return 0;
3131 3129
3132 rc = CIFSSMBNegotiate(xid, ses); 3130 rc = CIFSSMBNegotiate(xid, ses);
3133 if (rc == -EAGAIN) { 3131 if (rc == -EAGAIN) {
3134 /* retry only once on 1st time connection */ 3132 /* retry only once on 1st time connection */
3135 rc = CIFSSMBNegotiate(xid, ses); 3133 rc = CIFSSMBNegotiate(xid, ses);
3136 if (rc == -EAGAIN) 3134 if (rc == -EAGAIN)
3137 rc = -EHOSTDOWN; 3135 rc = -EHOSTDOWN;
3138 } 3136 }
3139 if (rc == 0) { 3137 if (rc == 0) {
3140 spin_lock(&GlobalMid_Lock); 3138 spin_lock(&GlobalMid_Lock);
3141 if (server->tcpStatus != CifsExiting) 3139 if (server->tcpStatus != CifsExiting)
3142 server->tcpStatus = CifsGood; 3140 server->tcpStatus = CifsGood;
3143 else 3141 else
3144 rc = -EHOSTDOWN; 3142 rc = -EHOSTDOWN;
3145 spin_unlock(&GlobalMid_Lock); 3143 spin_unlock(&GlobalMid_Lock);
3146 3144
3147 } 3145 }
3148 3146
3149 return rc; 3147 return rc;
3150 } 3148 }
3151 3149
3152 3150
3153 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, 3151 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3154 struct nls_table *nls_info) 3152 struct nls_table *nls_info)
3155 { 3153 {
3156 int rc = 0; 3154 int rc = 0;
3157 struct TCP_Server_Info *server = ses->server; 3155 struct TCP_Server_Info *server = ses->server;
3158 3156
3159 ses->flags = 0; 3157 ses->flags = 0;
3160 ses->capabilities = server->capabilities; 3158 ses->capabilities = server->capabilities;
3161 if (linuxExtEnabled == 0) 3159 if (linuxExtEnabled == 0)
3162 ses->capabilities &= (~CAP_UNIX); 3160 ses->capabilities &= (~CAP_UNIX);
3163 3161
3164 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 3162 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3165 server->secMode, server->capabilities, server->timeAdj); 3163 server->secMode, server->capabilities, server->timeAdj);
3166 3164
3167 rc = CIFS_SessSetup(xid, ses, nls_info); 3165 rc = CIFS_SessSetup(xid, ses, nls_info);
3168 if (rc) { 3166 if (rc) {
3169 cERROR(1, "Send error in SessSetup = %d", rc); 3167 cERROR(1, "Send error in SessSetup = %d", rc);
3170 } else { 3168 } else {
3171 mutex_lock(&ses->server->srv_mutex); 3169 mutex_lock(&ses->server->srv_mutex);
3172 if (!server->session_estab) { 3170 if (!server->session_estab) {
3173 server->session_key.response = ses->auth_key.response; 3171 server->session_key.response = ses->auth_key.response;
3174 server->session_key.len = ses->auth_key.len; 3172 server->session_key.len = ses->auth_key.len;
3175 server->sequence_number = 0x2; 3173 server->sequence_number = 0x2;
3176 server->session_estab = true; 3174 server->session_estab = true;
3177 ses->auth_key.response = NULL; 3175 ses->auth_key.response = NULL;
3178 } 3176 }
3179 mutex_unlock(&server->srv_mutex); 3177 mutex_unlock(&server->srv_mutex);
3180 3178
3181 cFYI(1, "CIFS Session Established successfully"); 3179 cFYI(1, "CIFS Session Established successfully");
3182 spin_lock(&GlobalMid_Lock); 3180 spin_lock(&GlobalMid_Lock);
3183 ses->status = CifsGood; 3181 ses->status = CifsGood;
3184 ses->need_reconnect = false; 3182 ses->need_reconnect = false;
3185 spin_unlock(&GlobalMid_Lock); 3183 spin_unlock(&GlobalMid_Lock);
3186 } 3184 }
3187 3185
3188 kfree(ses->auth_key.response); 3186 kfree(ses->auth_key.response);
3189 ses->auth_key.response = NULL; 3187 ses->auth_key.response = NULL;
3190 ses->auth_key.len = 0; 3188 ses->auth_key.len = 0;
3191 kfree(ses->ntlmssp); 3189 kfree(ses->ntlmssp);
3192 ses->ntlmssp = NULL; 3190 ses->ntlmssp = NULL;
3193 3191
3194 return rc; 3192 return rc;
3195 } 3193 }
3196 3194
3197 static struct cifsTconInfo * 3195 static struct cifsTconInfo *
3198 cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) 3196 cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3199 { 3197 {
3200 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb); 3198 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3201 struct cifsSesInfo *ses; 3199 struct cifsSesInfo *ses;
3202 struct cifsTconInfo *tcon = NULL; 3200 struct cifsTconInfo *tcon = NULL;
3203 struct smb_vol *vol_info; 3201 struct smb_vol *vol_info;
3204 char username[MAX_USERNAME_SIZE + 1]; 3202 char username[MAX_USERNAME_SIZE + 1];
3205 3203
3206 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL); 3204 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3207 if (vol_info == NULL) { 3205 if (vol_info == NULL) {
3208 tcon = ERR_PTR(-ENOMEM); 3206 tcon = ERR_PTR(-ENOMEM);
3209 goto out; 3207 goto out;
3210 } 3208 }
3211 3209
3212 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid); 3210 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3213 vol_info->username = username; 3211 vol_info->username = username;
3214 vol_info->local_nls = cifs_sb->local_nls; 3212 vol_info->local_nls = cifs_sb->local_nls;
3215 vol_info->linux_uid = fsuid; 3213 vol_info->linux_uid = fsuid;
3216 vol_info->cred_uid = fsuid; 3214 vol_info->cred_uid = fsuid;
3217 vol_info->UNC = master_tcon->treeName; 3215 vol_info->UNC = master_tcon->treeName;
3218 vol_info->retry = master_tcon->retry; 3216 vol_info->retry = master_tcon->retry;
3219 vol_info->nocase = master_tcon->nocase; 3217 vol_info->nocase = master_tcon->nocase;
3220 vol_info->local_lease = master_tcon->local_lease; 3218 vol_info->local_lease = master_tcon->local_lease;
3221 vol_info->no_linux_ext = !master_tcon->unix_ext; 3219 vol_info->no_linux_ext = !master_tcon->unix_ext;
3222 3220
3223 /* FIXME: allow for other secFlg settings */ 3221 /* FIXME: allow for other secFlg settings */
3224 vol_info->secFlg = CIFSSEC_MUST_KRB5; 3222 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3225 3223
3226 /* get a reference for the same TCP session */ 3224 /* get a reference for the same TCP session */
3227 spin_lock(&cifs_tcp_ses_lock); 3225 spin_lock(&cifs_tcp_ses_lock);
3228 ++master_tcon->ses->server->srv_count; 3226 ++master_tcon->ses->server->srv_count;
3229 spin_unlock(&cifs_tcp_ses_lock); 3227 spin_unlock(&cifs_tcp_ses_lock);
3230 3228
3231 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); 3229 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3232 if (IS_ERR(ses)) { 3230 if (IS_ERR(ses)) {
3233 tcon = (struct cifsTconInfo *)ses; 3231 tcon = (struct cifsTconInfo *)ses;
3234 cifs_put_tcp_session(master_tcon->ses->server); 3232 cifs_put_tcp_session(master_tcon->ses->server);
3235 goto out; 3233 goto out;
3236 } 3234 }
3237 3235
3238 tcon = cifs_get_tcon(ses, vol_info); 3236 tcon = cifs_get_tcon(ses, vol_info);
3239 if (IS_ERR(tcon)) { 3237 if (IS_ERR(tcon)) {
3240 cifs_put_smb_ses(ses); 3238 cifs_put_smb_ses(ses);
3241 goto out; 3239 goto out;
3242 } 3240 }
3243 3241
3244 if (ses->capabilities & CAP_UNIX) 3242 if (ses->capabilities & CAP_UNIX)
3245 reset_cifs_unix_caps(0, tcon, NULL, vol_info); 3243 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3246 out: 3244 out:
3247 kfree(vol_info); 3245 kfree(vol_info);
3248 3246
3249 return tcon; 3247 return tcon;
3250 } 3248 }
3251 3249
3252 static inline struct tcon_link * 3250 static inline struct tcon_link *
3253 cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) 3251 cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3254 { 3252 {
3255 return cifs_sb->master_tlink; 3253 return cifs_sb->master_tlink;
3256 } 3254 }
3257 3255
3258 struct cifsTconInfo * 3256 struct cifsTconInfo *
3259 cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) 3257 cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3260 { 3258 {
3261 return tlink_tcon(cifs_sb_master_tlink(cifs_sb)); 3259 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3262 } 3260 }
3263 3261
3264 static int 3262 static int
3265 cifs_sb_tcon_pending_wait(void *unused) 3263 cifs_sb_tcon_pending_wait(void *unused)
3266 { 3264 {
3267 schedule(); 3265 schedule();
3268 return signal_pending(current) ? -ERESTARTSYS : 0; 3266 return signal_pending(current) ? -ERESTARTSYS : 0;
3269 } 3267 }
3270 3268
3271 /* find and return a tlink with given uid */ 3269 /* find and return a tlink with given uid */
3272 static struct tcon_link * 3270 static struct tcon_link *
3273 tlink_rb_search(struct rb_root *root, uid_t uid) 3271 tlink_rb_search(struct rb_root *root, uid_t uid)
3274 { 3272 {
3275 struct rb_node *node = root->rb_node; 3273 struct rb_node *node = root->rb_node;
3276 struct tcon_link *tlink; 3274 struct tcon_link *tlink;
3277 3275
3278 while (node) { 3276 while (node) {
3279 tlink = rb_entry(node, struct tcon_link, tl_rbnode); 3277 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3280 3278
3281 if (tlink->tl_uid > uid) 3279 if (tlink->tl_uid > uid)
3282 node = node->rb_left; 3280 node = node->rb_left;
3283 else if (tlink->tl_uid < uid) 3281 else if (tlink->tl_uid < uid)
3284 node = node->rb_right; 3282 node = node->rb_right;
3285 else 3283 else
3286 return tlink; 3284 return tlink;
3287 } 3285 }
3288 return NULL; 3286 return NULL;
3289 } 3287 }
3290 3288
3291 /* insert a tcon_link into the tree */ 3289 /* insert a tcon_link into the tree */
3292 static void 3290 static void
3293 tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) 3291 tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
3294 { 3292 {
3295 struct rb_node **new = &(root->rb_node), *parent = NULL; 3293 struct rb_node **new = &(root->rb_node), *parent = NULL;
3296 struct tcon_link *tlink; 3294 struct tcon_link *tlink;
3297 3295
3298 while (*new) { 3296 while (*new) {
3299 tlink = rb_entry(*new, struct tcon_link, tl_rbnode); 3297 tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
3300 parent = *new; 3298 parent = *new;
3301 3299
3302 if (tlink->tl_uid > new_tlink->tl_uid) 3300 if (tlink->tl_uid > new_tlink->tl_uid)
3303 new = &((*new)->rb_left); 3301 new = &((*new)->rb_left);
3304 else 3302 else
3305 new = &((*new)->rb_right); 3303 new = &((*new)->rb_right);
3306 } 3304 }
3307 3305
3308 rb_link_node(&new_tlink->tl_rbnode, parent, new); 3306 rb_link_node(&new_tlink->tl_rbnode, parent, new);
3309 rb_insert_color(&new_tlink->tl_rbnode, root); 3307 rb_insert_color(&new_tlink->tl_rbnode, root);
3310 } 3308 }
3311 3309
3312 /* 3310 /*
3313 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the 3311 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3314 * current task. 3312 * current task.
3315 * 3313 *
3316 * If the superblock doesn't refer to a multiuser mount, then just return 3314 * If the superblock doesn't refer to a multiuser mount, then just return
3317 * the master tcon for the mount. 3315 * the master tcon for the mount.
3318 * 3316 *
3319 * First, search the rbtree for an existing tcon for this fsuid. If one 3317 * First, search the rbtree for an existing tcon for this fsuid. If one
3320 * exists, then check to see if it's pending construction. If it is then wait 3318 * exists, then check to see if it's pending construction. If it is then wait
3321 * for construction to complete. Once it's no longer pending, check to see if 3319 * for construction to complete. Once it's no longer pending, check to see if
3322 * it failed and either return an error or retry construction, depending on 3320 * it failed and either return an error or retry construction, depending on
3323 * the timeout. 3321 * the timeout.
3324 * 3322 *
3325 * If one doesn't exist then insert a new tcon_link struct into the tree and 3323 * If one doesn't exist then insert a new tcon_link struct into the tree and
3326 * try to construct a new one. 3324 * try to construct a new one.
3327 */ 3325 */
3328 struct tcon_link * 3326 struct tcon_link *
3329 cifs_sb_tlink(struct cifs_sb_info *cifs_sb) 3327 cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3330 { 3328 {
3331 int ret; 3329 int ret;
3332 uid_t fsuid = current_fsuid(); 3330 uid_t fsuid = current_fsuid();
3333 struct tcon_link *tlink, *newtlink; 3331 struct tcon_link *tlink, *newtlink;
3334 3332
3335 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) 3333 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3336 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); 3334 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3337 3335
3338 spin_lock(&cifs_sb->tlink_tree_lock); 3336 spin_lock(&cifs_sb->tlink_tree_lock);
3339 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); 3337 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3340 if (tlink) 3338 if (tlink)
3341 cifs_get_tlink(tlink); 3339 cifs_get_tlink(tlink);
3342 spin_unlock(&cifs_sb->tlink_tree_lock); 3340 spin_unlock(&cifs_sb->tlink_tree_lock);
3343 3341
3344 if (tlink == NULL) { 3342 if (tlink == NULL) {
3345 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); 3343 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3346 if (newtlink == NULL) 3344 if (newtlink == NULL)
3347 return ERR_PTR(-ENOMEM); 3345 return ERR_PTR(-ENOMEM);
3348 newtlink->tl_uid = fsuid; 3346 newtlink->tl_uid = fsuid;
3349 newtlink->tl_tcon = ERR_PTR(-EACCES); 3347 newtlink->tl_tcon = ERR_PTR(-EACCES);
3350 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); 3348 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3351 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); 3349 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3352 cifs_get_tlink(newtlink); 3350 cifs_get_tlink(newtlink);
3353 3351
3354 spin_lock(&cifs_sb->tlink_tree_lock); 3352 spin_lock(&cifs_sb->tlink_tree_lock);
3355 /* was one inserted after previous search? */ 3353 /* was one inserted after previous search? */
3356 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); 3354 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3357 if (tlink) { 3355 if (tlink) {
3358 cifs_get_tlink(tlink); 3356 cifs_get_tlink(tlink);
3359 spin_unlock(&cifs_sb->tlink_tree_lock); 3357 spin_unlock(&cifs_sb->tlink_tree_lock);
3360 kfree(newtlink); 3358 kfree(newtlink);
3361 goto wait_for_construction; 3359 goto wait_for_construction;
3362 } 3360 }
3363 tlink = newtlink; 3361 tlink = newtlink;
3364 tlink_rb_insert(&cifs_sb->tlink_tree, tlink); 3362 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
3365 spin_unlock(&cifs_sb->tlink_tree_lock); 3363 spin_unlock(&cifs_sb->tlink_tree_lock);
3366 } else { 3364 } else {
3367 wait_for_construction: 3365 wait_for_construction:
3368 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, 3366 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3369 cifs_sb_tcon_pending_wait, 3367 cifs_sb_tcon_pending_wait,
3370 TASK_INTERRUPTIBLE); 3368 TASK_INTERRUPTIBLE);
3371 if (ret) { 3369 if (ret) {
3372 cifs_put_tlink(tlink); 3370 cifs_put_tlink(tlink);
3373 return ERR_PTR(ret); 3371 return ERR_PTR(ret);
3374 } 3372 }
3375 3373
3376 /* if it's good, return it */ 3374 /* if it's good, return it */
3377 if (!IS_ERR(tlink->tl_tcon)) 3375 if (!IS_ERR(tlink->tl_tcon))
3378 return tlink; 3376 return tlink;
3379 3377
3380 /* return error if we tried this already recently */ 3378 /* return error if we tried this already recently */
3381 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) { 3379 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3382 cifs_put_tlink(tlink); 3380 cifs_put_tlink(tlink);
3383 return ERR_PTR(-EACCES); 3381 return ERR_PTR(-EACCES);
3384 } 3382 }
3385 3383
3386 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags)) 3384 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3387 goto wait_for_construction; 3385 goto wait_for_construction;
3388 } 3386 }
3389 3387
3390 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid); 3388 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3391 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags); 3389 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3392 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING); 3390 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3393 3391
3394 if (IS_ERR(tlink->tl_tcon)) { 3392 if (IS_ERR(tlink->tl_tcon)) {
3395 cifs_put_tlink(tlink); 3393 cifs_put_tlink(tlink);
3396 return ERR_PTR(-EACCES); 3394 return ERR_PTR(-EACCES);
3397 } 3395 }
3398 3396
3399 return tlink; 3397 return tlink;
3400 } 3398 }
3401 3399
3402 /* 3400 /*
3403 * periodic workqueue job that scans tcon_tree for a superblock and closes 3401 * periodic workqueue job that scans tcon_tree for a superblock and closes
3404 * out tcons. 3402 * out tcons.
3405 */ 3403 */
3406 static void 3404 static void
3407 cifs_prune_tlinks(struct work_struct *work) 3405 cifs_prune_tlinks(struct work_struct *work)
3408 { 3406 {
3409 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, 3407 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
3410 prune_tlinks.work); 3408 prune_tlinks.work);
3411 struct rb_root *root = &cifs_sb->tlink_tree; 3409 struct rb_root *root = &cifs_sb->tlink_tree;
3412 struct rb_node *node = rb_first(root); 3410 struct rb_node *node = rb_first(root);
3413 struct rb_node *tmp; 3411 struct rb_node *tmp;
3414 struct tcon_link *tlink; 3412 struct tcon_link *tlink;
3415 3413
3416 /* 3414 /*
3417 * Because we drop the spinlock in the loop in order to put the tlink 3415 * Because we drop the spinlock in the loop in order to put the tlink
3418 * it's not guarded against removal of links from the tree. The only 3416 * it's not guarded against removal of links from the tree. The only
3419 * places that remove entries from the tree are this function and 3417 * places that remove entries from the tree are this function and
3420 * umounts. Because this function is non-reentrant and is canceled 3418 * umounts. Because this function is non-reentrant and is canceled
3421 * before umount can proceed, this is safe. 3419 * before umount can proceed, this is safe.
3422 */ 3420 */
3423 spin_lock(&cifs_sb->tlink_tree_lock); 3421 spin_lock(&cifs_sb->tlink_tree_lock);
3424 node = rb_first(root); 3422 node = rb_first(root);
3425 while (node != NULL) { 3423 while (node != NULL) {
3426 tmp = node; 3424 tmp = node;
3427 node = rb_next(tmp); 3425 node = rb_next(tmp);
3428 tlink = rb_entry(tmp, struct tcon_link, tl_rbnode); 3426 tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
3429 3427
3430 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || 3428 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
3431 atomic_read(&tlink->tl_count) != 0 || 3429 atomic_read(&tlink->tl_count) != 0 ||
3432 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) 3430 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
3433 continue; 3431 continue;
3434 3432
3435 cifs_get_tlink(tlink); 3433 cifs_get_tlink(tlink);
3436 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); 3434 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3437 rb_erase(tmp, root); 3435 rb_erase(tmp, root);
3438 3436
3439 spin_unlock(&cifs_sb->tlink_tree_lock); 3437 spin_unlock(&cifs_sb->tlink_tree_lock);
3440 cifs_put_tlink(tlink); 3438 cifs_put_tlink(tlink);
3441 spin_lock(&cifs_sb->tlink_tree_lock); 3439 spin_lock(&cifs_sb->tlink_tree_lock);
3442 } 3440 }
3443 spin_unlock(&cifs_sb->tlink_tree_lock); 3441 spin_unlock(&cifs_sb->tlink_tree_lock);
3444 3442
3445 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, 3443 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
3446 TLINK_IDLE_EXPIRE); 3444 TLINK_IDLE_EXPIRE);
3447 } 3445 }
1 /* 1 /*
2 * fs/cifs/link.c 2 * fs/cifs/link.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2008 4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published 8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or 9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details. 15 * the GNU Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 #include <linux/fs.h> 21 #include <linux/fs.h>
22 #include <linux/stat.h> 22 #include <linux/stat.h>
23 #include <linux/slab.h> 23 #include <linux/slab.h>
24 #include <linux/namei.h> 24 #include <linux/namei.h>
25 #include "cifsfs.h" 25 #include "cifsfs.h"
26 #include "cifspdu.h" 26 #include "cifspdu.h"
27 #include "cifsglob.h" 27 #include "cifsglob.h"
28 #include "cifsproto.h" 28 #include "cifsproto.h"
29 #include "cifs_debug.h" 29 #include "cifs_debug.h"
30 #include "cifs_fs_sb.h" 30 #include "cifs_fs_sb.h"
31 31
32 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) 32 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
33 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) 33 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
34 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1)) 34 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
35 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024) 35 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
36 #define CIFS_MF_SYMLINK_FILE_SIZE \ 36 #define CIFS_MF_SYMLINK_FILE_SIZE \
37 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN) 37 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
38 38
39 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n" 39 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
40 #define CIFS_MF_SYMLINK_MD5_FORMAT \ 40 #define CIFS_MF_SYMLINK_MD5_FORMAT \
41 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n" 41 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n"
42 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \ 42 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \
43 md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \ 43 md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \
44 md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \ 44 md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \
45 md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\ 45 md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\
46 md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15] 46 md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
47 47
48 static int 48 static int
49 symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) 49 symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
50 { 50 {
51 int rc; 51 int rc;
52 unsigned int size; 52 unsigned int size;
53 struct crypto_shash *md5; 53 struct crypto_shash *md5;
54 struct sdesc *sdescmd5; 54 struct sdesc *sdescmd5;
55 55
56 md5 = crypto_alloc_shash("md5", 0, 0); 56 md5 = crypto_alloc_shash("md5", 0, 0);
57 if (!md5 || IS_ERR(md5)) { 57 if (IS_ERR(md5)) {
58 rc = PTR_ERR(md5);
59 cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); 58 cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc);
60 return rc; 59 return PTR_ERR(md5);
61 } 60 }
62 size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); 61 size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
63 sdescmd5 = kmalloc(size, GFP_KERNEL); 62 sdescmd5 = kmalloc(size, GFP_KERNEL);
64 if (!sdescmd5) { 63 if (!sdescmd5) {
65 rc = -ENOMEM; 64 rc = -ENOMEM;
66 cERROR(1, "%s: Memory allocation failure\n", __func__); 65 cERROR(1, "%s: Memory allocation failure\n", __func__);
67 goto symlink_hash_err; 66 goto symlink_hash_err;
68 } 67 }
69 sdescmd5->shash.tfm = md5; 68 sdescmd5->shash.tfm = md5;
70 sdescmd5->shash.flags = 0x0; 69 sdescmd5->shash.flags = 0x0;
71 70
72 rc = crypto_shash_init(&sdescmd5->shash); 71 rc = crypto_shash_init(&sdescmd5->shash);
73 if (rc) { 72 if (rc) {
74 cERROR(1, "%s: Could not init md5 shash\n", __func__); 73 cERROR(1, "%s: Could not init md5 shash\n", __func__);
75 goto symlink_hash_err; 74 goto symlink_hash_err;
76 } 75 }
77 crypto_shash_update(&sdescmd5->shash, link_str, link_len); 76 crypto_shash_update(&sdescmd5->shash, link_str, link_len);
78 rc = crypto_shash_final(&sdescmd5->shash, md5_hash); 77 rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
79 78
80 symlink_hash_err: 79 symlink_hash_err:
81 crypto_free_shash(md5); 80 crypto_free_shash(md5);
82 kfree(sdescmd5); 81 kfree(sdescmd5);
83 82
84 return rc; 83 return rc;
85 } 84 }
86 85
87 static int 86 static int
88 CIFSParseMFSymlink(const u8 *buf, 87 CIFSParseMFSymlink(const u8 *buf,
89 unsigned int buf_len, 88 unsigned int buf_len,
90 unsigned int *_link_len, 89 unsigned int *_link_len,
91 char **_link_str) 90 char **_link_str)
92 { 91 {
93 int rc; 92 int rc;
94 unsigned int link_len; 93 unsigned int link_len;
95 const char *md5_str1; 94 const char *md5_str1;
96 const char *link_str; 95 const char *link_str;
97 u8 md5_hash[16]; 96 u8 md5_hash[16];
98 char md5_str2[34]; 97 char md5_str2[34];
99 98
100 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) 99 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
101 return -EINVAL; 100 return -EINVAL;
102 101
103 md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET]; 102 md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
104 link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET]; 103 link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
105 104
106 rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len); 105 rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
107 if (rc != 1) 106 if (rc != 1)
108 return -EINVAL; 107 return -EINVAL;
109 108
110 rc = symlink_hash(link_len, link_str, md5_hash); 109 rc = symlink_hash(link_len, link_str, md5_hash);
111 if (rc) { 110 if (rc) {
112 cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc); 111 cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
113 return rc; 112 return rc;
114 } 113 }
115 114
116 snprintf(md5_str2, sizeof(md5_str2), 115 snprintf(md5_str2, sizeof(md5_str2),
117 CIFS_MF_SYMLINK_MD5_FORMAT, 116 CIFS_MF_SYMLINK_MD5_FORMAT,
118 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 117 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
119 118
120 if (strncmp(md5_str1, md5_str2, 17) != 0) 119 if (strncmp(md5_str1, md5_str2, 17) != 0)
121 return -EINVAL; 120 return -EINVAL;
122 121
123 if (_link_str) { 122 if (_link_str) {
124 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL); 123 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
125 if (!*_link_str) 124 if (!*_link_str)
126 return -ENOMEM; 125 return -ENOMEM;
127 } 126 }
128 127
129 *_link_len = link_len; 128 *_link_len = link_len;
130 return 0; 129 return 0;
131 } 130 }
132 131
133 static int 132 static int
134 CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) 133 CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
135 { 134 {
136 int rc; 135 int rc;
137 unsigned int link_len; 136 unsigned int link_len;
138 unsigned int ofs; 137 unsigned int ofs;
139 u8 md5_hash[16]; 138 u8 md5_hash[16];
140 139
141 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) 140 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
142 return -EINVAL; 141 return -EINVAL;
143 142
144 link_len = strlen(link_str); 143 link_len = strlen(link_str);
145 144
146 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) 145 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
147 return -ENAMETOOLONG; 146 return -ENAMETOOLONG;
148 147
149 rc = symlink_hash(link_len, link_str, md5_hash); 148 rc = symlink_hash(link_len, link_str, md5_hash);
150 if (rc) { 149 if (rc) {
151 cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc); 150 cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
152 return rc; 151 return rc;
153 } 152 }
154 153
155 snprintf(buf, buf_len, 154 snprintf(buf, buf_len,
156 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT, 155 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
157 link_len, 156 link_len,
158 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 157 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
159 158
160 ofs = CIFS_MF_SYMLINK_LINK_OFFSET; 159 ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
161 memcpy(buf + ofs, link_str, link_len); 160 memcpy(buf + ofs, link_str, link_len);
162 161
163 ofs += link_len; 162 ofs += link_len;
164 if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) { 163 if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
165 buf[ofs] = '\n'; 164 buf[ofs] = '\n';
166 ofs++; 165 ofs++;
167 } 166 }
168 167
169 while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) { 168 while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
170 buf[ofs] = ' '; 169 buf[ofs] = ' ';
171 ofs++; 170 ofs++;
172 } 171 }
173 172
174 return 0; 173 return 0;
175 } 174 }
176 175
177 static int 176 static int
178 CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon, 177 CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
179 const char *fromName, const char *toName, 178 const char *fromName, const char *toName,
180 const struct nls_table *nls_codepage, int remap) 179 const struct nls_table *nls_codepage, int remap)
181 { 180 {
182 int rc; 181 int rc;
183 int oplock = 0; 182 int oplock = 0;
184 __u16 netfid = 0; 183 __u16 netfid = 0;
185 u8 *buf; 184 u8 *buf;
186 unsigned int bytes_written = 0; 185 unsigned int bytes_written = 0;
187 186
188 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 187 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
189 if (!buf) 188 if (!buf)
190 return -ENOMEM; 189 return -ENOMEM;
191 190
192 rc = CIFSFormatMFSymlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); 191 rc = CIFSFormatMFSymlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName);
193 if (rc != 0) { 192 if (rc != 0) {
194 kfree(buf); 193 kfree(buf);
195 return rc; 194 return rc;
196 } 195 }
197 196
198 rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE, 197 rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
199 CREATE_NOT_DIR, &netfid, &oplock, NULL, 198 CREATE_NOT_DIR, &netfid, &oplock, NULL,
200 nls_codepage, remap); 199 nls_codepage, remap);
201 if (rc != 0) { 200 if (rc != 0) {
202 kfree(buf); 201 kfree(buf);
203 return rc; 202 return rc;
204 } 203 }
205 204
206 rc = CIFSSMBWrite(xid, tcon, netfid, 205 rc = CIFSSMBWrite(xid, tcon, netfid,
207 CIFS_MF_SYMLINK_FILE_SIZE /* length */, 206 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
208 0 /* offset */, 207 0 /* offset */,
209 &bytes_written, buf, NULL, 0); 208 &bytes_written, buf, NULL, 0);
210 CIFSSMBClose(xid, tcon, netfid); 209 CIFSSMBClose(xid, tcon, netfid);
211 kfree(buf); 210 kfree(buf);
212 if (rc != 0) 211 if (rc != 0)
213 return rc; 212 return rc;
214 213
215 if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) 214 if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
216 return -EIO; 215 return -EIO;
217 216
218 return 0; 217 return 0;
219 } 218 }
220 219
221 static int 220 static int
222 CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon, 221 CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
223 const unsigned char *searchName, char **symlinkinfo, 222 const unsigned char *searchName, char **symlinkinfo,
224 const struct nls_table *nls_codepage, int remap) 223 const struct nls_table *nls_codepage, int remap)
225 { 224 {
226 int rc; 225 int rc;
227 int oplock = 0; 226 int oplock = 0;
228 __u16 netfid = 0; 227 __u16 netfid = 0;
229 u8 *buf; 228 u8 *buf;
230 char *pbuf; 229 char *pbuf;
231 unsigned int bytes_read = 0; 230 unsigned int bytes_read = 0;
232 int buf_type = CIFS_NO_BUFFER; 231 int buf_type = CIFS_NO_BUFFER;
233 unsigned int link_len = 0; 232 unsigned int link_len = 0;
234 FILE_ALL_INFO file_info; 233 FILE_ALL_INFO file_info;
235 234
236 rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ, 235 rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
237 CREATE_NOT_DIR, &netfid, &oplock, &file_info, 236 CREATE_NOT_DIR, &netfid, &oplock, &file_info,
238 nls_codepage, remap); 237 nls_codepage, remap);
239 if (rc != 0) 238 if (rc != 0)
240 return rc; 239 return rc;
241 240
242 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) { 241 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
243 CIFSSMBClose(xid, tcon, netfid); 242 CIFSSMBClose(xid, tcon, netfid);
244 /* it's not a symlink */ 243 /* it's not a symlink */
245 return -EINVAL; 244 return -EINVAL;
246 } 245 }
247 246
248 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 247 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
249 if (!buf) 248 if (!buf)
250 return -ENOMEM; 249 return -ENOMEM;
251 pbuf = buf; 250 pbuf = buf;
252 251
253 rc = CIFSSMBRead(xid, tcon, netfid, 252 rc = CIFSSMBRead(xid, tcon, netfid,
254 CIFS_MF_SYMLINK_FILE_SIZE /* length */, 253 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
255 0 /* offset */, 254 0 /* offset */,
256 &bytes_read, &pbuf, &buf_type); 255 &bytes_read, &pbuf, &buf_type);
257 CIFSSMBClose(xid, tcon, netfid); 256 CIFSSMBClose(xid, tcon, netfid);
258 if (rc != 0) { 257 if (rc != 0) {
259 kfree(buf); 258 kfree(buf);
260 return rc; 259 return rc;
261 } 260 }
262 261
263 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo); 262 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
264 kfree(buf); 263 kfree(buf);
265 if (rc != 0) 264 if (rc != 0)
266 return rc; 265 return rc;
267 266
268 return 0; 267 return 0;
269 } 268 }
270 269
271 bool 270 bool
272 CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr) 271 CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr)
273 { 272 {
274 if (!(fattr->cf_mode & S_IFREG)) 273 if (!(fattr->cf_mode & S_IFREG))
275 /* it's not a symlink */ 274 /* it's not a symlink */
276 return false; 275 return false;
277 276
278 if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE) 277 if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
279 /* it's not a symlink */ 278 /* it's not a symlink */
280 return false; 279 return false;
281 280
282 return true; 281 return true;
283 } 282 }
284 283
285 int 284 int
286 CIFSCheckMFSymlink(struct cifs_fattr *fattr, 285 CIFSCheckMFSymlink(struct cifs_fattr *fattr,
287 const unsigned char *path, 286 const unsigned char *path,
288 struct cifs_sb_info *cifs_sb, int xid) 287 struct cifs_sb_info *cifs_sb, int xid)
289 { 288 {
290 int rc; 289 int rc;
291 int oplock = 0; 290 int oplock = 0;
292 __u16 netfid = 0; 291 __u16 netfid = 0;
293 struct tcon_link *tlink; 292 struct tcon_link *tlink;
294 struct cifsTconInfo *pTcon; 293 struct cifsTconInfo *pTcon;
295 u8 *buf; 294 u8 *buf;
296 char *pbuf; 295 char *pbuf;
297 unsigned int bytes_read = 0; 296 unsigned int bytes_read = 0;
298 int buf_type = CIFS_NO_BUFFER; 297 int buf_type = CIFS_NO_BUFFER;
299 unsigned int link_len = 0; 298 unsigned int link_len = 0;
300 FILE_ALL_INFO file_info; 299 FILE_ALL_INFO file_info;
301 300
302 if (!CIFSCouldBeMFSymlink(fattr)) 301 if (!CIFSCouldBeMFSymlink(fattr))
303 /* it's not a symlink */ 302 /* it's not a symlink */
304 return 0; 303 return 0;
305 304
306 tlink = cifs_sb_tlink(cifs_sb); 305 tlink = cifs_sb_tlink(cifs_sb);
307 if (IS_ERR(tlink)) 306 if (IS_ERR(tlink))
308 return PTR_ERR(tlink); 307 return PTR_ERR(tlink);
309 pTcon = tlink_tcon(tlink); 308 pTcon = tlink_tcon(tlink);
310 309
311 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, 310 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
312 CREATE_NOT_DIR, &netfid, &oplock, &file_info, 311 CREATE_NOT_DIR, &netfid, &oplock, &file_info,
313 cifs_sb->local_nls, 312 cifs_sb->local_nls,
314 cifs_sb->mnt_cifs_flags & 313 cifs_sb->mnt_cifs_flags &
315 CIFS_MOUNT_MAP_SPECIAL_CHR); 314 CIFS_MOUNT_MAP_SPECIAL_CHR);
316 if (rc != 0) 315 if (rc != 0)
317 goto out; 316 goto out;
318 317
319 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) { 318 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
320 CIFSSMBClose(xid, pTcon, netfid); 319 CIFSSMBClose(xid, pTcon, netfid);
321 /* it's not a symlink */ 320 /* it's not a symlink */
322 goto out; 321 goto out;
323 } 322 }
324 323
325 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 324 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
326 if (!buf) { 325 if (!buf) {
327 rc = -ENOMEM; 326 rc = -ENOMEM;
328 goto out; 327 goto out;
329 } 328 }
330 pbuf = buf; 329 pbuf = buf;
331 330
332 rc = CIFSSMBRead(xid, pTcon, netfid, 331 rc = CIFSSMBRead(xid, pTcon, netfid,
333 CIFS_MF_SYMLINK_FILE_SIZE /* length */, 332 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
334 0 /* offset */, 333 0 /* offset */,
335 &bytes_read, &pbuf, &buf_type); 334 &bytes_read, &pbuf, &buf_type);
336 CIFSSMBClose(xid, pTcon, netfid); 335 CIFSSMBClose(xid, pTcon, netfid);
337 if (rc != 0) { 336 if (rc != 0) {
338 kfree(buf); 337 kfree(buf);
339 goto out; 338 goto out;
340 } 339 }
341 340
342 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL); 341 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
343 kfree(buf); 342 kfree(buf);
344 if (rc == -EINVAL) { 343 if (rc == -EINVAL) {
345 /* it's not a symlink */ 344 /* it's not a symlink */
346 rc = 0; 345 rc = 0;
347 goto out; 346 goto out;
348 } 347 }
349 348
350 if (rc != 0) 349 if (rc != 0)
351 goto out; 350 goto out;
352 351
353 /* it is a symlink */ 352 /* it is a symlink */
354 fattr->cf_eof = link_len; 353 fattr->cf_eof = link_len;
355 fattr->cf_mode &= ~S_IFMT; 354 fattr->cf_mode &= ~S_IFMT;
356 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; 355 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
357 fattr->cf_dtype = DT_LNK; 356 fattr->cf_dtype = DT_LNK;
358 out: 357 out:
359 cifs_put_tlink(tlink); 358 cifs_put_tlink(tlink);
360 return rc; 359 return rc;
361 } 360 }
362 361
363 int 362 int
364 cifs_hardlink(struct dentry *old_file, struct inode *inode, 363 cifs_hardlink(struct dentry *old_file, struct inode *inode,
365 struct dentry *direntry) 364 struct dentry *direntry)
366 { 365 {
367 int rc = -EACCES; 366 int rc = -EACCES;
368 int xid; 367 int xid;
369 char *fromName = NULL; 368 char *fromName = NULL;
370 char *toName = NULL; 369 char *toName = NULL;
371 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 370 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
372 struct tcon_link *tlink; 371 struct tcon_link *tlink;
373 struct cifsTconInfo *pTcon; 372 struct cifsTconInfo *pTcon;
374 struct cifsInodeInfo *cifsInode; 373 struct cifsInodeInfo *cifsInode;
375 374
376 tlink = cifs_sb_tlink(cifs_sb); 375 tlink = cifs_sb_tlink(cifs_sb);
377 if (IS_ERR(tlink)) 376 if (IS_ERR(tlink))
378 return PTR_ERR(tlink); 377 return PTR_ERR(tlink);
379 pTcon = tlink_tcon(tlink); 378 pTcon = tlink_tcon(tlink);
380 379
381 xid = GetXid(); 380 xid = GetXid();
382 381
383 fromName = build_path_from_dentry(old_file); 382 fromName = build_path_from_dentry(old_file);
384 toName = build_path_from_dentry(direntry); 383 toName = build_path_from_dentry(direntry);
385 if ((fromName == NULL) || (toName == NULL)) { 384 if ((fromName == NULL) || (toName == NULL)) {
386 rc = -ENOMEM; 385 rc = -ENOMEM;
387 goto cifs_hl_exit; 386 goto cifs_hl_exit;
388 } 387 }
389 388
390 if (pTcon->unix_ext) 389 if (pTcon->unix_ext)
391 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, 390 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
392 cifs_sb->local_nls, 391 cifs_sb->local_nls,
393 cifs_sb->mnt_cifs_flags & 392 cifs_sb->mnt_cifs_flags &
394 CIFS_MOUNT_MAP_SPECIAL_CHR); 393 CIFS_MOUNT_MAP_SPECIAL_CHR);
395 else { 394 else {
396 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, 395 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
397 cifs_sb->local_nls, 396 cifs_sb->local_nls,
398 cifs_sb->mnt_cifs_flags & 397 cifs_sb->mnt_cifs_flags &
399 CIFS_MOUNT_MAP_SPECIAL_CHR); 398 CIFS_MOUNT_MAP_SPECIAL_CHR);
400 if ((rc == -EIO) || (rc == -EINVAL)) 399 if ((rc == -EIO) || (rc == -EINVAL))
401 rc = -EOPNOTSUPP; 400 rc = -EOPNOTSUPP;
402 } 401 }
403 402
404 d_drop(direntry); /* force new lookup from server of target */ 403 d_drop(direntry); /* force new lookup from server of target */
405 404
406 /* if source file is cached (oplocked) revalidate will not go to server 405 /* if source file is cached (oplocked) revalidate will not go to server
407 until the file is closed or oplock broken so update nlinks locally */ 406 until the file is closed or oplock broken so update nlinks locally */
408 if (old_file->d_inode) { 407 if (old_file->d_inode) {
409 cifsInode = CIFS_I(old_file->d_inode); 408 cifsInode = CIFS_I(old_file->d_inode);
410 if (rc == 0) { 409 if (rc == 0) {
411 old_file->d_inode->i_nlink++; 410 old_file->d_inode->i_nlink++;
412 /* BB should we make this contingent on superblock flag NOATIME? */ 411 /* BB should we make this contingent on superblock flag NOATIME? */
413 /* old_file->d_inode->i_ctime = CURRENT_TIME;*/ 412 /* old_file->d_inode->i_ctime = CURRENT_TIME;*/
414 /* parent dir timestamps will update from srv 413 /* parent dir timestamps will update from srv
415 within a second, would it really be worth it 414 within a second, would it really be worth it
416 to set the parent dir cifs inode time to zero 415 to set the parent dir cifs inode time to zero
417 to force revalidate (faster) for it too? */ 416 to force revalidate (faster) for it too? */
418 } 417 }
419 /* if not oplocked will force revalidate to get info 418 /* if not oplocked will force revalidate to get info
420 on source file from srv */ 419 on source file from srv */
421 cifsInode->time = 0; 420 cifsInode->time = 0;
422 421
423 /* Will update parent dir timestamps from srv within a second. 422 /* Will update parent dir timestamps from srv within a second.
424 Would it really be worth it to set the parent dir (cifs 423 Would it really be worth it to set the parent dir (cifs
425 inode) time field to zero to force revalidate on parent 424 inode) time field to zero to force revalidate on parent
426 directory faster ie 425 directory faster ie
427 CIFS_I(inode)->time = 0; */ 426 CIFS_I(inode)->time = 0; */
428 } 427 }
429 428
430 cifs_hl_exit: 429 cifs_hl_exit:
431 kfree(fromName); 430 kfree(fromName);
432 kfree(toName); 431 kfree(toName);
433 FreeXid(xid); 432 FreeXid(xid);
434 cifs_put_tlink(tlink); 433 cifs_put_tlink(tlink);
435 return rc; 434 return rc;
436 } 435 }
437 436
438 void * 437 void *
439 cifs_follow_link(struct dentry *direntry, struct nameidata *nd) 438 cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
440 { 439 {
441 struct inode *inode = direntry->d_inode; 440 struct inode *inode = direntry->d_inode;
442 int rc = -ENOMEM; 441 int rc = -ENOMEM;
443 int xid; 442 int xid;
444 char *full_path = NULL; 443 char *full_path = NULL;
445 char *target_path = NULL; 444 char *target_path = NULL;
446 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 445 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
447 struct tcon_link *tlink = NULL; 446 struct tcon_link *tlink = NULL;
448 struct cifsTconInfo *tcon; 447 struct cifsTconInfo *tcon;
449 448
450 xid = GetXid(); 449 xid = GetXid();
451 450
452 tlink = cifs_sb_tlink(cifs_sb); 451 tlink = cifs_sb_tlink(cifs_sb);
453 if (IS_ERR(tlink)) { 452 if (IS_ERR(tlink)) {
454 rc = PTR_ERR(tlink); 453 rc = PTR_ERR(tlink);
455 tlink = NULL; 454 tlink = NULL;
456 goto out; 455 goto out;
457 } 456 }
458 tcon = tlink_tcon(tlink); 457 tcon = tlink_tcon(tlink);
459 458
460 /* 459 /*
461 * For now, we just handle symlinks with unix extensions enabled. 460 * For now, we just handle symlinks with unix extensions enabled.
462 * Eventually we should handle NTFS reparse points, and MacOS 461 * Eventually we should handle NTFS reparse points, and MacOS
463 * symlink support. For instance... 462 * symlink support. For instance...
464 * 463 *
465 * rc = CIFSSMBQueryReparseLinkInfo(...) 464 * rc = CIFSSMBQueryReparseLinkInfo(...)
466 * 465 *
467 * For now, just return -EACCES when the server doesn't support posix 466 * For now, just return -EACCES when the server doesn't support posix
468 * extensions. Note that we still allow querying symlinks when posix 467 * extensions. Note that we still allow querying symlinks when posix
469 * extensions are manually disabled. We could disable these as well 468 * extensions are manually disabled. We could disable these as well
470 * but there doesn't seem to be any harm in allowing the client to 469 * but there doesn't seem to be any harm in allowing the client to
471 * read them. 470 * read them.
472 */ 471 */
473 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) 472 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
474 && !(tcon->ses->capabilities & CAP_UNIX)) { 473 && !(tcon->ses->capabilities & CAP_UNIX)) {
475 rc = -EACCES; 474 rc = -EACCES;
476 goto out; 475 goto out;
477 } 476 }
478 477
479 full_path = build_path_from_dentry(direntry); 478 full_path = build_path_from_dentry(direntry);
480 if (!full_path) 479 if (!full_path)
481 goto out; 480 goto out;
482 481
483 cFYI(1, "Full path: %s inode = 0x%p", full_path, inode); 482 cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
484 483
485 rc = -EACCES; 484 rc = -EACCES;
486 /* 485 /*
487 * First try Minshall+French Symlinks, if configured 486 * First try Minshall+French Symlinks, if configured
488 * and fallback to UNIX Extensions Symlinks. 487 * and fallback to UNIX Extensions Symlinks.
489 */ 488 */
490 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) 489 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
491 rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path, 490 rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
492 cifs_sb->local_nls, 491 cifs_sb->local_nls,
493 cifs_sb->mnt_cifs_flags & 492 cifs_sb->mnt_cifs_flags &
494 CIFS_MOUNT_MAP_SPECIAL_CHR); 493 CIFS_MOUNT_MAP_SPECIAL_CHR);
495 494
496 if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX)) 495 if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
497 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, 496 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
498 cifs_sb->local_nls); 497 cifs_sb->local_nls);
499 498
500 kfree(full_path); 499 kfree(full_path);
501 out: 500 out:
502 if (rc != 0) { 501 if (rc != 0) {
503 kfree(target_path); 502 kfree(target_path);
504 target_path = ERR_PTR(rc); 503 target_path = ERR_PTR(rc);
505 } 504 }
506 505
507 FreeXid(xid); 506 FreeXid(xid);
508 if (tlink) 507 if (tlink)
509 cifs_put_tlink(tlink); 508 cifs_put_tlink(tlink);
510 nd_set_link(nd, target_path); 509 nd_set_link(nd, target_path);
511 return NULL; 510 return NULL;
512 } 511 }
513 512
514 int 513 int
515 cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) 514 cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
516 { 515 {
517 int rc = -EOPNOTSUPP; 516 int rc = -EOPNOTSUPP;
518 int xid; 517 int xid;
519 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 518 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
520 struct tcon_link *tlink; 519 struct tcon_link *tlink;
521 struct cifsTconInfo *pTcon; 520 struct cifsTconInfo *pTcon;
522 char *full_path = NULL; 521 char *full_path = NULL;
523 struct inode *newinode = NULL; 522 struct inode *newinode = NULL;
524 523
525 xid = GetXid(); 524 xid = GetXid();
526 525
527 tlink = cifs_sb_tlink(cifs_sb); 526 tlink = cifs_sb_tlink(cifs_sb);
528 if (IS_ERR(tlink)) { 527 if (IS_ERR(tlink)) {
529 rc = PTR_ERR(tlink); 528 rc = PTR_ERR(tlink);
530 goto symlink_exit; 529 goto symlink_exit;
531 } 530 }
532 pTcon = tlink_tcon(tlink); 531 pTcon = tlink_tcon(tlink);
533 532
534 full_path = build_path_from_dentry(direntry); 533 full_path = build_path_from_dentry(direntry);
535 if (full_path == NULL) { 534 if (full_path == NULL) {
536 rc = -ENOMEM; 535 rc = -ENOMEM;
537 goto symlink_exit; 536 goto symlink_exit;
538 } 537 }
539 538
540 cFYI(1, "Full path: %s", full_path); 539 cFYI(1, "Full path: %s", full_path);
541 cFYI(1, "symname is %s", symname); 540 cFYI(1, "symname is %s", symname);
542 541
543 /* BB what if DFS and this volume is on different share? BB */ 542 /* BB what if DFS and this volume is on different share? BB */
544 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) 543 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
545 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname, 544 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
546 cifs_sb->local_nls, 545 cifs_sb->local_nls,
547 cifs_sb->mnt_cifs_flags & 546 cifs_sb->mnt_cifs_flags &
548 CIFS_MOUNT_MAP_SPECIAL_CHR); 547 CIFS_MOUNT_MAP_SPECIAL_CHR);
549 else if (pTcon->unix_ext) 548 else if (pTcon->unix_ext)
550 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 549 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
551 cifs_sb->local_nls); 550 cifs_sb->local_nls);
552 /* else 551 /* else
553 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName, 552 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
554 cifs_sb_target->local_nls); */ 553 cifs_sb_target->local_nls); */
555 554
556 if (rc == 0) { 555 if (rc == 0) {
557 if (pTcon->unix_ext) 556 if (pTcon->unix_ext)
558 rc = cifs_get_inode_info_unix(&newinode, full_path, 557 rc = cifs_get_inode_info_unix(&newinode, full_path,
559 inode->i_sb, xid); 558 inode->i_sb, xid);
560 else 559 else
561 rc = cifs_get_inode_info(&newinode, full_path, NULL, 560 rc = cifs_get_inode_info(&newinode, full_path, NULL,
562 inode->i_sb, xid, NULL); 561 inode->i_sb, xid, NULL);
563 562
564 if (rc != 0) { 563 if (rc != 0) {
565 cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d", 564 cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d",
566 rc); 565 rc);
567 } else { 566 } else {
568 d_instantiate(direntry, newinode); 567 d_instantiate(direntry, newinode);
569 } 568 }
570 } 569 }
571 symlink_exit: 570 symlink_exit:
572 kfree(full_path); 571 kfree(full_path);
573 cifs_put_tlink(tlink); 572 cifs_put_tlink(tlink);
574 FreeXid(xid); 573 FreeXid(xid);
575 return rc; 574 return rc;
576 } 575 }
577 576
578 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie) 577 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
579 { 578 {
580 char *p = nd_get_link(nd); 579 char *p = nd_get_link(nd);
581 if (!IS_ERR(p)) 580 if (!IS_ERR(p))
582 kfree(p); 581 kfree(p);
583 } 582 }
584 583
fs/cifs/md4.c
1 /* File was deleted
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 a implementation of MD4 designed for use in the SMB authentication protocol
5 Copyright (C) Andrew Tridgell 1997-1998.
6 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 #include <linux/module.h>
23 #include <linux/fs.h>
24 #include "cifsencrypt.h"
25
26 /* NOTE: This code makes no attempt to be fast! */
27
28 static __u32
29 F(__u32 X, __u32 Y, __u32 Z)
30 {
31 return (X & Y) | ((~X) & Z);
32 }
33
34 static __u32
35 G(__u32 X, __u32 Y, __u32 Z)
36 {
37 return (X & Y) | (X & Z) | (Y & Z);
38 }
39
40 static __u32
41 H(__u32 X, __u32 Y, __u32 Z)
42 {
43 return X ^ Y ^ Z;
44 }
45
46 static __u32
47 lshift(__u32 x, int s)
48 {
49 x &= 0xFFFFFFFF;
50 return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
51 }
52
53 #define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s)
54 #define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0x5A827999,s)
55 #define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0x6ED9EBA1,s)
56
57 /* this applies md4 to 64 byte chunks */
58 static void
59 mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D)
60 {
61 int j;
62 __u32 AA, BB, CC, DD;
63 __u32 X[16];
64
65
66 for (j = 0; j < 16; j++)
67 X[j] = M[j];
68
69 AA = *A;
70 BB = *B;
71 CC = *C;
72 DD = *D;
73
74 ROUND1(A, B, C, D, 0, 3);
75 ROUND1(D, A, B, C, 1, 7);
76 ROUND1(C, D, A, B, 2, 11);
77 ROUND1(B, C, D, A, 3, 19);
78 ROUND1(A, B, C, D, 4, 3);
79 ROUND1(D, A, B, C, 5, 7);
80 ROUND1(C, D, A, B, 6, 11);
81 ROUND1(B, C, D, A, 7, 19);
82 ROUND1(A, B, C, D, 8, 3);
83 ROUND1(D, A, B, C, 9, 7);
84 ROUND1(C, D, A, B, 10, 11);
85 ROUND1(B, C, D, A, 11, 19);
86 ROUND1(A, B, C, D, 12, 3);
87 ROUND1(D, A, B, C, 13, 7);
88 ROUND1(C, D, A, B, 14, 11);
89 ROUND1(B, C, D, A, 15, 19);
90
91 ROUND2(A, B, C, D, 0, 3);
92 ROUND2(D, A, B, C, 4, 5);
93 ROUND2(C, D, A, B, 8, 9);
94 ROUND2(B, C, D, A, 12, 13);
95 ROUND2(A, B, C, D, 1, 3);
96 ROUND2(D, A, B, C, 5, 5);
97 ROUND2(C, D, A, B, 9, 9);
98 ROUND2(B, C, D, A, 13, 13);
99 ROUND2(A, B, C, D, 2, 3);
100 ROUND2(D, A, B, C, 6, 5);
101 ROUND2(C, D, A, B, 10, 9);
102 ROUND2(B, C, D, A, 14, 13);
103 ROUND2(A, B, C, D, 3, 3);
104 ROUND2(D, A, B, C, 7, 5);
105 ROUND2(C, D, A, B, 11, 9);
106 ROUND2(B, C, D, A, 15, 13);
107
108 ROUND3(A, B, C, D, 0, 3);
109 ROUND3(D, A, B, C, 8, 9);
110 ROUND3(C, D, A, B, 4, 11);
111 ROUND3(B, C, D, A, 12, 15);
112 ROUND3(A, B, C, D, 2, 3);
113 ROUND3(D, A, B, C, 10, 9);
114 ROUND3(C, D, A, B, 6, 11);
115 ROUND3(B, C, D, A, 14, 15);
116 ROUND3(A, B, C, D, 1, 3);
117 ROUND3(D, A, B, C, 9, 9);
118 ROUND3(C, D, A, B, 5, 11);
119 ROUND3(B, C, D, A, 13, 15);
120 ROUND3(A, B, C, D, 3, 3);
121 ROUND3(D, A, B, C, 11, 9);
122 ROUND3(C, D, A, B, 7, 11);
123 ROUND3(B, C, D, A, 15, 15);
124
125 *A += AA;
126 *B += BB;
127 *C += CC;
128 *D += DD;
129
130 *A &= 0xFFFFFFFF;
131 *B &= 0xFFFFFFFF;
132 *C &= 0xFFFFFFFF;
133 *D &= 0xFFFFFFFF;
134
135 for (j = 0; j < 16; j++)
136 X[j] = 0;
137 }
138
139 static void
140 copy64(__u32 *M, unsigned char *in)
141 {
142 int i;
143
144 for (i = 0; i < 16; i++)
145 M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
146 (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
147 }
148
149 static void
150 copy4(unsigned char *out, __u32 x)
151 {
152 out[0] = x & 0xFF;
153 out[1] = (x >> 8) & 0xFF;
154 out[2] = (x >> 16) & 0xFF;
155 out[3] = (x >> 24) & 0xFF;
156 }
157
158 /* produce a md4 message digest from data of length n bytes */
159 void
160 mdfour(unsigned char *out, unsigned char *in, int n)
161 {
162 unsigned char buf[128];
163 __u32 M[16];
164 __u32 b = n * 8;
165 int i;
166 __u32 A = 0x67452301;
167 __u32 B = 0xefcdab89;
168 __u32 C = 0x98badcfe;
169 __u32 D = 0x10325476;
170
171 while (n > 64) {
172 copy64(M, in);
173 mdfour64(M, &A, &B, &C, &D);
174 in += 64;
175 n -= 64;
176 }
177
178 for (i = 0; i < 128; i++)
179 buf[i] = 0;
180 memcpy(buf, in, n);
181 buf[n] = 0x80;
182
183 if (n <= 55) {
184 copy4(buf + 56, b);
185 copy64(M, buf);
186 mdfour64(M, &A, &B, &C, &D);
187 } else {
188 copy4(buf + 120, b);
189 copy64(M, buf);
190 mdfour64(M, &A, &B, &C, &D);
191 copy64(M, buf + 64);
192 mdfour64(M, &A, &B, &C, &D);
193 }
194
195 for (i = 0; i < 128; i++)
196 buf[i] = 0;
197 copy64(M, buf);
198
199 copy4(out, A);
200 copy4(out + 4, B);
201 copy4(out + 8, C);
202 copy4(out + 12, D);
203
204 A = B = C = D = 0;
205 }
206 1 /*
1 /* 1 /*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 4
5 a partial implementation of DES designed for use in the 5 a partial implementation of DES designed for use in the
6 SMB authentication protocol 6 SMB authentication protocol
7 7
8 Copyright (C) Andrew Tridgell 1998 8 Copyright (C) Andrew Tridgell 1998
9 Modified by Steve French (sfrench@us.ibm.com) 2002,2004 9 Modified by Steve French (sfrench@us.ibm.com) 2002,2004
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 (at your option) any later version.
15 15
16 This program is distributed in the hope that it will be useful, 16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */ 24 */
25 25
26 /* NOTES: 26 /* NOTES:
27 27
28 This code makes no attempt to be fast! In fact, it is a very 28 This code makes no attempt to be fast! In fact, it is a very
29 slow implementation 29 slow implementation
30 30
31 This code is NOT a complete DES implementation. It implements only 31 This code is NOT a complete DES implementation. It implements only
32 the minimum necessary for SMB authentication, as used by all SMB 32 the minimum necessary for SMB authentication, as used by all SMB
33 products (including every copy of Microsoft Windows95 ever sold) 33 products (including every copy of Microsoft Windows95 ever sold)
34 34
35 In particular, it can only do a unchained forward DES pass. This 35 In particular, it can only do a unchained forward DES pass. This
36 means it is not possible to use this code for encryption/decryption 36 means it is not possible to use this code for encryption/decryption
37 of data, instead it is only useful as a "hash" algorithm. 37 of data, instead it is only useful as a "hash" algorithm.
38 38
39 There is no entry point into this code that allows normal DES operation. 39 There is no entry point into this code that allows normal DES operation.
40 40
41 I believe this means that this code does not come under ITAR 41 I believe this means that this code does not come under ITAR
42 regulations but this is NOT a legal opinion. If you are concerned 42 regulations but this is NOT a legal opinion. If you are concerned
43 about the applicability of ITAR regulations to this code then you 43 about the applicability of ITAR regulations to this code then you
44 should confirm it for yourself (and maybe let me know if you come 44 should confirm it for yourself (and maybe let me know if you come
45 up with a different answer to the one above) 45 up with a different answer to the one above)
46 */ 46 */
47 #include <linux/slab.h> 47 #include <linux/slab.h>
48 #include "cifsencrypt.h"
49 #define uchar unsigned char 48 #define uchar unsigned char
50 49
51 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9, 50 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
52 1, 58, 50, 42, 34, 26, 18, 51 1, 58, 50, 42, 34, 26, 18,
53 10, 2, 59, 51, 43, 35, 27, 52 10, 2, 59, 51, 43, 35, 27,
54 19, 11, 3, 60, 52, 44, 36, 53 19, 11, 3, 60, 52, 44, 36,
55 63, 55, 47, 39, 31, 23, 15, 54 63, 55, 47, 39, 31, 23, 15,
56 7, 62, 54, 46, 38, 30, 22, 55 7, 62, 54, 46, 38, 30, 22,
57 14, 6, 61, 53, 45, 37, 29, 56 14, 6, 61, 53, 45, 37, 29,
58 21, 13, 5, 28, 20, 12, 4 57 21, 13, 5, 28, 20, 12, 4
59 }; 58 };
60 59
61 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5, 60 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
62 3, 28, 15, 6, 21, 10, 61 3, 28, 15, 6, 21, 10,
63 23, 19, 12, 4, 26, 8, 62 23, 19, 12, 4, 26, 8,
64 16, 7, 27, 20, 13, 2, 63 16, 7, 27, 20, 13, 2,
65 41, 52, 31, 37, 47, 55, 64 41, 52, 31, 37, 47, 55,
66 30, 40, 51, 45, 33, 48, 65 30, 40, 51, 45, 33, 48,
67 44, 49, 39, 56, 34, 53, 66 44, 49, 39, 56, 34, 53,
68 46, 42, 50, 36, 29, 32 67 46, 42, 50, 36, 29, 32
69 }; 68 };
70 69
71 static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 70 static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
72 60, 52, 44, 36, 28, 20, 12, 4, 71 60, 52, 44, 36, 28, 20, 12, 4,
73 62, 54, 46, 38, 30, 22, 14, 6, 72 62, 54, 46, 38, 30, 22, 14, 6,
74 64, 56, 48, 40, 32, 24, 16, 8, 73 64, 56, 48, 40, 32, 24, 16, 8,
75 57, 49, 41, 33, 25, 17, 9, 1, 74 57, 49, 41, 33, 25, 17, 9, 1,
76 59, 51, 43, 35, 27, 19, 11, 3, 75 59, 51, 43, 35, 27, 19, 11, 3,
77 61, 53, 45, 37, 29, 21, 13, 5, 76 61, 53, 45, 37, 29, 21, 13, 5,
78 63, 55, 47, 39, 31, 23, 15, 7 77 63, 55, 47, 39, 31, 23, 15, 7
79 }; 78 };
80 79
81 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, 80 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
82 4, 5, 6, 7, 8, 9, 81 4, 5, 6, 7, 8, 9,
83 8, 9, 10, 11, 12, 13, 82 8, 9, 10, 11, 12, 13,
84 12, 13, 14, 15, 16, 17, 83 12, 13, 14, 15, 16, 17,
85 16, 17, 18, 19, 20, 21, 84 16, 17, 18, 19, 20, 21,
86 20, 21, 22, 23, 24, 25, 85 20, 21, 22, 23, 24, 25,
87 24, 25, 26, 27, 28, 29, 86 24, 25, 26, 27, 28, 29,
88 28, 29, 30, 31, 32, 1 87 28, 29, 30, 31, 32, 1
89 }; 88 };
90 89
91 static uchar perm5[32] = { 16, 7, 20, 21, 90 static uchar perm5[32] = { 16, 7, 20, 21,
92 29, 12, 28, 17, 91 29, 12, 28, 17,
93 1, 15, 23, 26, 92 1, 15, 23, 26,
94 5, 18, 31, 10, 93 5, 18, 31, 10,
95 2, 8, 24, 14, 94 2, 8, 24, 14,
96 32, 27, 3, 9, 95 32, 27, 3, 9,
97 19, 13, 30, 6, 96 19, 13, 30, 6,
98 22, 11, 4, 25 97 22, 11, 4, 25
99 }; 98 };
100 99
101 static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32, 100 static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
102 39, 7, 47, 15, 55, 23, 63, 31, 101 39, 7, 47, 15, 55, 23, 63, 31,
103 38, 6, 46, 14, 54, 22, 62, 30, 102 38, 6, 46, 14, 54, 22, 62, 30,
104 37, 5, 45, 13, 53, 21, 61, 29, 103 37, 5, 45, 13, 53, 21, 61, 29,
105 36, 4, 44, 12, 52, 20, 60, 28, 104 36, 4, 44, 12, 52, 20, 60, 28,
106 35, 3, 43, 11, 51, 19, 59, 27, 105 35, 3, 43, 11, 51, 19, 59, 27,
107 34, 2, 42, 10, 50, 18, 58, 26, 106 34, 2, 42, 10, 50, 18, 58, 26,
108 33, 1, 41, 9, 49, 17, 57, 25 107 33, 1, 41, 9, 49, 17, 57, 25
109 }; 108 };
110 109
111 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; 110 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
112 111
113 static uchar sbox[8][4][16] = { 112 static uchar sbox[8][4][16] = {
114 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, 113 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
115 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, 114 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
116 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, 115 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
117 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} }, 116 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} },
118 117
119 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, 118 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
120 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, 119 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
121 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, 120 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
122 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} }, 121 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} },
123 122
124 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, 123 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
125 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, 124 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
126 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, 125 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
127 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} }, 126 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} },
128 127
129 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, 128 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
130 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, 129 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
131 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, 130 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
132 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} }, 131 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} },
133 132
134 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, 133 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
135 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, 134 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
136 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, 135 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
137 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} }, 136 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} },
138 137
139 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, 138 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
140 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, 139 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
141 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, 140 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
142 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} }, 141 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} },
143 142
144 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, 143 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
145 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, 144 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
146 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, 145 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
147 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} }, 146 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} },
148 147
149 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, 148 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
150 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, 149 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
151 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, 150 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
152 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} } 151 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} }
153 }; 152 };
154 153
155 static void 154 static void
156 permute(char *out, char *in, uchar *p, int n) 155 permute(char *out, char *in, uchar *p, int n)
157 { 156 {
158 int i; 157 int i;
159 for (i = 0; i < n; i++) 158 for (i = 0; i < n; i++)
160 out[i] = in[p[i] - 1]; 159 out[i] = in[p[i] - 1];
161 } 160 }
162 161
163 static void 162 static void
164 lshift(char *d, int count, int n) 163 lshift(char *d, int count, int n)
165 { 164 {
166 char out[64]; 165 char out[64];
167 int i; 166 int i;
168 for (i = 0; i < n; i++) 167 for (i = 0; i < n; i++)
169 out[i] = d[(i + count) % n]; 168 out[i] = d[(i + count) % n];
170 for (i = 0; i < n; i++) 169 for (i = 0; i < n; i++)
171 d[i] = out[i]; 170 d[i] = out[i];
172 } 171 }
173 172
174 static void 173 static void
175 concat(char *out, char *in1, char *in2, int l1, int l2) 174 concat(char *out, char *in1, char *in2, int l1, int l2)
176 { 175 {
177 while (l1--) 176 while (l1--)
178 *out++ = *in1++; 177 *out++ = *in1++;
179 while (l2--) 178 while (l2--)
180 *out++ = *in2++; 179 *out++ = *in2++;
181 } 180 }
182 181
183 static void 182 static void
184 xor(char *out, char *in1, char *in2, int n) 183 xor(char *out, char *in1, char *in2, int n)
185 { 184 {
186 int i; 185 int i;
187 for (i = 0; i < n; i++) 186 for (i = 0; i < n; i++)
188 out[i] = in1[i] ^ in2[i]; 187 out[i] = in1[i] ^ in2[i];
189 } 188 }
190 189
191 static void 190 static void
192 dohash(char *out, char *in, char *key, int forw) 191 dohash(char *out, char *in, char *key, int forw)
193 { 192 {
194 int i, j, k; 193 int i, j, k;
195 char *pk1; 194 char *pk1;
196 char c[28]; 195 char c[28];
197 char d[28]; 196 char d[28];
198 char *cd; 197 char *cd;
199 char (*ki)[48]; 198 char (*ki)[48];
200 char *pd1; 199 char *pd1;
201 char l[32], r[32]; 200 char l[32], r[32];
202 char *rl; 201 char *rl;
203 202
204 /* Have to reduce stack usage */ 203 /* Have to reduce stack usage */
205 pk1 = kmalloc(56+56+64+64, GFP_KERNEL); 204 pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
206 if (pk1 == NULL) 205 if (pk1 == NULL)
207 return; 206 return;
208 207
209 ki = kmalloc(16*48, GFP_KERNEL); 208 ki = kmalloc(16*48, GFP_KERNEL);
210 if (ki == NULL) { 209 if (ki == NULL) {
211 kfree(pk1); 210 kfree(pk1);
212 return; 211 return;
213 } 212 }
214 213
215 cd = pk1 + 56; 214 cd = pk1 + 56;
216 pd1 = cd + 56; 215 pd1 = cd + 56;
217 rl = pd1 + 64; 216 rl = pd1 + 64;
218 217
219 permute(pk1, key, perm1, 56); 218 permute(pk1, key, perm1, 56);
220 219
221 for (i = 0; i < 28; i++) 220 for (i = 0; i < 28; i++)
222 c[i] = pk1[i]; 221 c[i] = pk1[i];
223 for (i = 0; i < 28; i++) 222 for (i = 0; i < 28; i++)
224 d[i] = pk1[i + 28]; 223 d[i] = pk1[i + 28];
225 224
226 for (i = 0; i < 16; i++) { 225 for (i = 0; i < 16; i++) {
227 lshift(c, sc[i], 28); 226 lshift(c, sc[i], 28);
228 lshift(d, sc[i], 28); 227 lshift(d, sc[i], 28);
229 228
230 concat(cd, c, d, 28, 28); 229 concat(cd, c, d, 28, 28);
231 permute(ki[i], cd, perm2, 48); 230 permute(ki[i], cd, perm2, 48);
232 } 231 }
233 232
234 permute(pd1, in, perm3, 64); 233 permute(pd1, in, perm3, 64);
235 234
236 for (j = 0; j < 32; j++) { 235 for (j = 0; j < 32; j++) {
237 l[j] = pd1[j]; 236 l[j] = pd1[j];
238 r[j] = pd1[j + 32]; 237 r[j] = pd1[j + 32];
239 } 238 }
240 239
241 for (i = 0; i < 16; i++) { 240 for (i = 0; i < 16; i++) {
242 char *er; /* er[48] */ 241 char *er; /* er[48] */
243 char *erk; /* erk[48] */ 242 char *erk; /* erk[48] */
244 char b[8][6]; 243 char b[8][6];
245 char *cb; /* cb[32] */ 244 char *cb; /* cb[32] */
246 char *pcb; /* pcb[32] */ 245 char *pcb; /* pcb[32] */
247 char *r2; /* r2[32] */ 246 char *r2; /* r2[32] */
248 247
249 er = kmalloc(48+48+32+32+32, GFP_KERNEL); 248 er = kmalloc(48+48+32+32+32, GFP_KERNEL);
250 if (er == NULL) { 249 if (er == NULL) {
251 kfree(pk1); 250 kfree(pk1);
252 kfree(ki); 251 kfree(ki);
253 return; 252 return;
254 } 253 }
255 erk = er+48; 254 erk = er+48;
256 cb = erk+48; 255 cb = erk+48;
257 pcb = cb+32; 256 pcb = cb+32;
258 r2 = pcb+32; 257 r2 = pcb+32;
259 258
260 permute(er, r, perm4, 48); 259 permute(er, r, perm4, 48);
261 260
262 xor(erk, er, ki[forw ? i : 15 - i], 48); 261 xor(erk, er, ki[forw ? i : 15 - i], 48);
263 262
264 for (j = 0; j < 8; j++) 263 for (j = 0; j < 8; j++)
265 for (k = 0; k < 6; k++) 264 for (k = 0; k < 6; k++)
266 b[j][k] = erk[j * 6 + k]; 265 b[j][k] = erk[j * 6 + k];
267 266
268 for (j = 0; j < 8; j++) { 267 for (j = 0; j < 8; j++) {
269 int m, n; 268 int m, n;
270 m = (b[j][0] << 1) | b[j][5]; 269 m = (b[j][0] << 1) | b[j][5];
271 270
272 n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 271 n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] <<
273 1) | b[j][4]; 272 1) | b[j][4];
274 273
275 for (k = 0; k < 4; k++) 274 for (k = 0; k < 4; k++)
276 b[j][k] = 275 b[j][k] =
277 (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0; 276 (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
278 } 277 }
279 278
280 for (j = 0; j < 8; j++) 279 for (j = 0; j < 8; j++)
281 for (k = 0; k < 4; k++) 280 for (k = 0; k < 4; k++)
282 cb[j * 4 + k] = b[j][k]; 281 cb[j * 4 + k] = b[j][k];
283 permute(pcb, cb, perm5, 32); 282 permute(pcb, cb, perm5, 32);
284 283
285 xor(r2, l, pcb, 32); 284 xor(r2, l, pcb, 32);
286 285
287 for (j = 0; j < 32; j++) 286 for (j = 0; j < 32; j++)
288 l[j] = r[j]; 287 l[j] = r[j];
289 288
290 for (j = 0; j < 32; j++) 289 for (j = 0; j < 32; j++)
291 r[j] = r2[j]; 290 r[j] = r2[j];
292 291
293 kfree(er); 292 kfree(er);
294 } 293 }
295 294
296 concat(rl, r, l, 32, 32); 295 concat(rl, r, l, 32, 32);
297 296
298 permute(out, rl, perm6, 64); 297 permute(out, rl, perm6, 64);
299 kfree(pk1); 298 kfree(pk1);
300 kfree(ki); 299 kfree(ki);
301 } 300 }
302 301
303 static void 302 static void
304 str_to_key(unsigned char *str, unsigned char *key) 303 str_to_key(unsigned char *str, unsigned char *key)
305 { 304 {
306 int i; 305 int i;
307 306
308 key[0] = str[0] >> 1; 307 key[0] = str[0] >> 1;
309 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2); 308 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
310 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3); 309 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
311 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4); 310 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
312 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5); 311 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
313 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6); 312 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
314 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7); 313 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
315 key[7] = str[6] & 0x7F; 314 key[7] = str[6] & 0x7F;
316 for (i = 0; i < 8; i++) 315 for (i = 0; i < 8; i++)
317 key[i] = (key[i] << 1); 316 key[i] = (key[i] << 1);
318 } 317 }
319 318
320 static void 319 static void
321 smbhash(unsigned char *out, const unsigned char *in, unsigned char *key, 320 smbhash(unsigned char *out, const unsigned char *in, unsigned char *key,
322 int forw) 321 int forw)
323 { 322 {
324 int i; 323 int i;
325 char *outb; /* outb[64] */ 324 char *outb; /* outb[64] */
326 char *inb; /* inb[64] */ 325 char *inb; /* inb[64] */
327 char *keyb; /* keyb[64] */ 326 char *keyb; /* keyb[64] */
328 unsigned char key2[8]; 327 unsigned char key2[8];
329 328
330 outb = kmalloc(64 * 3, GFP_KERNEL); 329 outb = kmalloc(64 * 3, GFP_KERNEL);
331 if (outb == NULL) 330 if (outb == NULL)
332 return; 331 return;
333 332
334 inb = outb + 64; 333 inb = outb + 64;
335 keyb = inb + 64; 334 keyb = inb + 64;
336 335
337 str_to_key(key, key2); 336 str_to_key(key, key2);
338 337
339 for (i = 0; i < 64; i++) { 338 for (i = 0; i < 64; i++) {
340 inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; 339 inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
341 keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; 340 keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
342 outb[i] = 0; 341 outb[i] = 0;
343 } 342 }
344 343
345 dohash(outb, inb, keyb, forw); 344 dohash(outb, inb, keyb, forw);
346 345
347 for (i = 0; i < 8; i++) 346 for (i = 0; i < 8; i++)
348 out[i] = 0; 347 out[i] = 0;
349 348
350 for (i = 0; i < 64; i++) { 349 for (i = 0; i < 64; i++) {
351 if (outb[i]) 350 if (outb[i])
352 out[i / 8] |= (1 << (7 - (i % 8))); 351 out[i / 8] |= (1 << (7 - (i % 8)));
353 } 352 }
354 kfree(outb); 353 kfree(outb);
355 } 354 }
356 355
357 void 356 void
358 E_P16(unsigned char *p14, unsigned char *p16) 357 E_P16(unsigned char *p14, unsigned char *p16)
359 { 358 {
360 unsigned char sp8[8] = 359 unsigned char sp8[8] =
361 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; 360 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
362 smbhash(p16, sp8, p14, 1); 361 smbhash(p16, sp8, p14, 1);
363 smbhash(p16 + 8, sp8, p14 + 7, 1); 362 smbhash(p16 + 8, sp8, p14 + 7, 1);
364 } 363 }
365 364
366 void 365 void
367 E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24) 366 E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
368 { 367 {
369 smbhash(p24, c8, p21, 1); 368 smbhash(p24, c8, p21, 1);
370 smbhash(p24 + 8, c8, p21 + 7, 1); 369 smbhash(p24 + 8, c8, p21 + 7, 1);
371 smbhash(p24 + 16, c8, p21 + 14, 1); 370 smbhash(p24 + 16, c8, p21 + 14, 1);
372 } 371 }
373 372
374 #if 0 /* currently unused */ 373 #if 0 /* currently unused */
375 static void 374 static void
376 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) 375 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
377 { 376 {
378 smbhash(out, in, p14, 0); 377 smbhash(out, in, p14, 0);
379 smbhash(out + 8, in + 8, p14 + 7, 0); 378 smbhash(out + 8, in + 8, p14 + 7, 0);
380 } 379 }
381 380
382 static void 381 static void
383 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out) 382 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
384 { 383 {
385 smbhash(out, in, p14, 1); 384 smbhash(out, in, p14, 1);
386 smbhash(out + 8, in + 8, p14 + 7, 1); 385 smbhash(out + 8, in + 8, p14 + 7, 1);
387 } 386 }
388 /* these routines are currently unneeded, but may be 387 /* these routines are currently unneeded, but may be
389 needed later */ 388 needed later */
390 void 389 void
391 cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key) 390 cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key)
392 { 391 {
393 unsigned char buf[8]; 392 unsigned char buf[8];
394 393
395 smbhash(buf, in, key, 1); 394 smbhash(buf, in, key, 1);
396 smbhash(out, buf, key + 9, 1); 395 smbhash(out, buf, key + 9, 1);
397 } 396 }
398 397
399 void 398 void
400 cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key) 399 cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key)
401 { 400 {
402 unsigned char buf[8]; 401 unsigned char buf[8];
403 static unsigned char key2[8]; 402 static unsigned char key2[8];
404 403
405 smbhash(buf, in, key, 1); 404 smbhash(buf, in, key, 1);
406 key2[0] = key[7]; 405 key2[0] = key[7];
407 smbhash(out, buf, key2, 1); 406 smbhash(out, buf, key2, 1);
408 } 407 }
409 408
410 void 409 void
411 cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw) 410 cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
412 { 411 {
413 static unsigned char key2[8]; 412 static unsigned char key2[8];
414 413
415 smbhash(out, in, key, forw); 414 smbhash(out, in, key, forw);
416 key2[0] = key[7]; 415 key2[0] = key[7];
417 smbhash(out + 8, in + 8, key2, forw); 416 smbhash(out + 8, in + 8, key2, forw);
418 } 417 }
419 #endif /* unneeded routines */ 418 #endif /* unneeded routines */
420 419
fs/cifs/smbencrypt.c
1 /* 1 /*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 SMB parameters and setup 4 SMB parameters and setup
5 Copyright (C) Andrew Tridgell 1992-2000 5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
7 Modified by Jeremy Allison 1995. 7 Modified by Jeremy Allison 1995.
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003 9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 (at your option) any later version.
15 15
16 This program is distributed in the hope that it will be useful, 16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */ 24 */
25 25
26 #include <linux/module.h> 26 #include <linux/module.h>
27 #include <linux/slab.h> 27 #include <linux/slab.h>
28 #include <linux/fs.h> 28 #include <linux/fs.h>
29 #include <linux/string.h> 29 #include <linux/string.h>
30 #include <linux/kernel.h> 30 #include <linux/kernel.h>
31 #include <linux/random.h> 31 #include <linux/random.h>
32 #include "cifs_unicode.h" 32 #include "cifs_unicode.h"
33 #include "cifspdu.h" 33 #include "cifspdu.h"
34 #include "cifsglob.h" 34 #include "cifsglob.h"
35 #include "cifs_debug.h" 35 #include "cifs_debug.h"
36 #include "cifsencrypt.h" 36 #include "cifsproto.h"
37 37
38 #ifndef false 38 #ifndef false
39 #define false 0 39 #define false 0
40 #endif 40 #endif
41 #ifndef true 41 #ifndef true
42 #define true 1 42 #define true 1
43 #endif 43 #endif
44 44
45 /* following came from the other byteorder.h to avoid include conflicts */ 45 /* following came from the other byteorder.h to avoid include conflicts */
46 #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) 46 #define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
47 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) 47 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
48 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val))) 48 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
49 49
50 /*The following definitions come from libsmb/smbencrypt.c */ 50 /* produce a md4 message digest from data of length n bytes */
51 int
52 mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
53 {
54 int rc;
55 unsigned int size;
56 struct crypto_shash *md4;
57 struct sdesc *sdescmd4;
51 58
52 void SMBencrypt(unsigned char *passwd, const unsigned char *c8, 59 md4 = crypto_alloc_shash("md4", 0, 0);
53 unsigned char *p24); 60 if (IS_ERR(md4)) {
54 void E_md4hash(const unsigned char *passwd, unsigned char *p16); 61 cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
55 static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, 62 return PTR_ERR(md4);
56 unsigned char p24[24]); 63 }
57 void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 64 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
65 sdescmd4 = kmalloc(size, GFP_KERNEL);
66 if (!sdescmd4) {
67 rc = -ENOMEM;
68 cERROR(1, "%s: Memory allocation failure\n", __func__);
69 goto mdfour_err;
70 }
71 sdescmd4->shash.tfm = md4;
72 sdescmd4->shash.flags = 0x0;
58 73
74 rc = crypto_shash_init(&sdescmd4->shash);
75 if (rc) {
76 cERROR(1, "%s: Could not init md4 shash\n", __func__);
77 goto mdfour_err;
78 }
79 crypto_shash_update(&sdescmd4->shash, link_str, link_len);
80 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
81
82 mdfour_err:
83 crypto_free_shash(md4);
84 kfree(sdescmd4);
85
86 return rc;
87 }
88
89 /* Does the des encryption from the NT or LM MD4 hash. */
90 static void
91 SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
92 unsigned char p24[24])
93 {
94 unsigned char p21[21];
95
96 memset(p21, '\0', 21);
97
98 memcpy(p21, passwd, 16);
99 E_P24(p21, c8, p24);
100 }
101
59 /* 102 /*
60 This implements the X/Open SMB password encryption 103 This implements the X/Open SMB password encryption
61 It takes a password, a 8 byte "crypt key" and puts 24 bytes of 104 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
62 encrypted password into p24 */ 105 encrypted password into p24 */
63 /* Note that password must be uppercased and null terminated */ 106 /* Note that password must be uppercased and null terminated */
64 void 107 void
65 SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) 108 SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
66 { 109 {
67 unsigned char p14[15], p21[21]; 110 unsigned char p14[15], p21[21];
68 111
69 memset(p21, '\0', 21); 112 memset(p21, '\0', 21);
70 memset(p14, '\0', 14); 113 memset(p14, '\0', 14);
71 strncpy((char *) p14, (char *) passwd, 14); 114 strncpy((char *) p14, (char *) passwd, 14);
72 115
73 /* strupper((char *)p14); *//* BB at least uppercase the easy range */ 116 /* strupper((char *)p14); *//* BB at least uppercase the easy range */
74 E_P16(p14, p21); 117 E_P16(p14, p21);
75 118
76 SMBOWFencrypt(p21, c8, p24); 119 SMBOWFencrypt(p21, c8, p24);
77 120
78 memset(p14, 0, 15); 121 memset(p14, 0, 15);
79 memset(p21, 0, 21); 122 memset(p21, 0, 21);
80 } 123 }
81 124
82 /* Routines for Windows NT MD4 Hash functions. */ 125 /* Routines for Windows NT MD4 Hash functions. */
83 static int 126 static int
84 _my_wcslen(__u16 *str) 127 _my_wcslen(__u16 *str)
85 { 128 {
86 int len = 0; 129 int len = 0;
87 while (*str++ != 0) 130 while (*str++ != 0)
88 len++; 131 len++;
89 return len; 132 return len;
90 } 133 }
91 134
92 /* 135 /*
93 * Convert a string into an NT UNICODE string. 136 * Convert a string into an NT UNICODE string.
94 * Note that regardless of processor type 137 * Note that regardless of processor type
95 * this must be in intel (little-endian) 138 * this must be in intel (little-endian)
96 * format. 139 * format.
97 */ 140 */
98 141
99 static int 142 static int
100 _my_mbstowcs(__u16 *dst, const unsigned char *src, int len) 143 _my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
101 { /* BB not a very good conversion routine - change/fix */ 144 { /* BB not a very good conversion routine - change/fix */
102 int i; 145 int i;
103 __u16 val; 146 __u16 val;
104 147
105 for (i = 0; i < len; i++) { 148 for (i = 0; i < len; i++) {
106 val = *src; 149 val = *src;
107 SSVAL(dst, 0, val); 150 SSVAL(dst, 0, val);
108 dst++; 151 dst++;
109 src++; 152 src++;
110 if (val == 0) 153 if (val == 0)
111 break; 154 break;
112 } 155 }
113 return i; 156 return i;
114 } 157 }
115 158
116 /* 159 /*
117 * Creates the MD4 Hash of the users password in NT UNICODE. 160 * Creates the MD4 Hash of the users password in NT UNICODE.
118 */ 161 */
119 162
120 void 163 int
121 E_md4hash(const unsigned char *passwd, unsigned char *p16) 164 E_md4hash(const unsigned char *passwd, unsigned char *p16)
122 { 165 {
166 int rc;
123 int len; 167 int len;
124 __u16 wpwd[129]; 168 __u16 wpwd[129];
125 169
126 /* Password cannot be longer than 128 characters */ 170 /* Password cannot be longer than 128 characters */
127 if (passwd) { 171 if (passwd) {
128 len = strlen((char *) passwd); 172 len = strlen((char *) passwd);
129 if (len > 128) 173 if (len > 128)
130 len = 128; 174 len = 128;
131 175
132 /* Password must be converted to NT unicode */ 176 /* Password must be converted to NT unicode */
133 _my_mbstowcs(wpwd, passwd, len); 177 _my_mbstowcs(wpwd, passwd, len);
134 } else 178 } else
135 len = 0; 179 len = 0;
136 180
137 wpwd[len] = 0; /* Ensure string is null terminated */ 181 wpwd[len] = 0; /* Ensure string is null terminated */
138 /* Calculate length in bytes */ 182 /* Calculate length in bytes */
139 len = _my_wcslen(wpwd) * sizeof(__u16); 183 len = _my_wcslen(wpwd) * sizeof(__u16);
140 184
141 mdfour(p16, (unsigned char *) wpwd, len); 185 rc = mdfour(p16, (unsigned char *) wpwd, len);
142 memset(wpwd, 0, 129 * 2); 186 memset(wpwd, 0, 129 * 2);
187
188 return rc;
143 } 189 }
144 190
145 #if 0 /* currently unused */ 191 #if 0 /* currently unused */
146 /* Does both the NT and LM owfs of a user's password */ 192 /* Does both the NT and LM owfs of a user's password */
147 static void 193 static void
148 nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) 194 nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
149 { 195 {
150 char passwd[514]; 196 char passwd[514];
151 197
152 memset(passwd, '\0', 514); 198 memset(passwd, '\0', 514);
153 if (strlen(pwd) < 513) 199 if (strlen(pwd) < 513)
154 strcpy(passwd, pwd); 200 strcpy(passwd, pwd);
155 else 201 else
156 memcpy(passwd, pwd, 512); 202 memcpy(passwd, pwd, 512);
157 /* Calculate the MD4 hash (NT compatible) of the password */ 203 /* Calculate the MD4 hash (NT compatible) of the password */
158 memset(nt_p16, '\0', 16); 204 memset(nt_p16, '\0', 16);
159 E_md4hash(passwd, nt_p16); 205 E_md4hash(passwd, nt_p16);
160 206
161 /* Mangle the passwords into Lanman format */ 207 /* Mangle the passwords into Lanman format */
162 passwd[14] = '\0'; 208 passwd[14] = '\0';
163 /* strupper(passwd); */ 209 /* strupper(passwd); */
164 210
165 /* Calculate the SMB (lanman) hash functions of the password */ 211 /* Calculate the SMB (lanman) hash functions of the password */
166 212
167 memset(p16, '\0', 16); 213 memset(p16, '\0', 16);
168 E_P16((unsigned char *) passwd, (unsigned char *) p16); 214 E_P16((unsigned char *) passwd, (unsigned char *) p16);
169 215
170 /* clear out local copy of user's password (just being paranoid). */ 216 /* clear out local copy of user's password (just being paranoid). */
171 memset(passwd, '\0', sizeof(passwd)); 217 memset(passwd, '\0', sizeof(passwd));
172 } 218 }
173 #endif 219 #endif
174 220
175 /* Does the NTLMv2 owfs of a user's password */ 221 /* Does the NTLMv2 owfs of a user's password */
176 #if 0 /* function not needed yet - but will be soon */ 222 #if 0 /* function not needed yet - but will be soon */
177 static void 223 static void
178 ntv2_owf_gen(const unsigned char owf[16], const char *user_n, 224 ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
179 const char *domain_n, unsigned char kr_buf[16], 225 const char *domain_n, unsigned char kr_buf[16],
180 const struct nls_table *nls_codepage) 226 const struct nls_table *nls_codepage)
181 { 227 {
182 wchar_t *user_u; 228 wchar_t *user_u;
183 wchar_t *dom_u; 229 wchar_t *dom_u;
184 int user_l, domain_l; 230 int user_l, domain_l;
185 struct HMACMD5Context ctx; 231 struct HMACMD5Context ctx;
186 232
187 /* might as well do one alloc to hold both (user_u and dom_u) */ 233 /* might as well do one alloc to hold both (user_u and dom_u) */
188 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL); 234 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
189 if (user_u == NULL) 235 if (user_u == NULL)
190 return; 236 return;
191 dom_u = user_u + 1024; 237 dom_u = user_u + 1024;
192 238
193 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, 239 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,
194 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); 240 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
195 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, 241 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,
196 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */ 242 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
197 243
198 /* BB user and domain may need to be uppercased */ 244 /* BB user and domain may need to be uppercased */
199 user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage); 245 user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
200 domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage); 246 domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
201 247
202 user_l++; /* trailing null */ 248 user_l++; /* trailing null */
203 domain_l++; 249 domain_l++;
204 250
205 hmac_md5_init_limK_to_64(owf, 16, &ctx); 251 hmac_md5_init_limK_to_64(owf, 16, &ctx);
206 hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx); 252 hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
207 hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx); 253 hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
208 hmac_md5_final(kr_buf, &ctx); 254 hmac_md5_final(kr_buf, &ctx);
209 255
210 kfree(user_u); 256 kfree(user_u);
211 } 257 }
212 #endif 258 #endif
213 259
214 /* Does the des encryption from the NT or LM MD4 hash. */
215 static void
216 SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
217 unsigned char p24[24])
218 {
219 unsigned char p21[21];
220
221 memset(p21, '\0', 21);
222
223 memcpy(p21, passwd, 16);
224 E_P24(p21, c8, p24);
225 }
226
227 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 260 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
228 #if 0 /* currently unused */ 261 #if 0 /* currently unused */
229 static void 262 static void
230 NTLMSSPOWFencrypt(unsigned char passwd[8], 263 NTLMSSPOWFencrypt(unsigned char passwd[8],
231 unsigned char *ntlmchalresp, unsigned char p24[24]) 264 unsigned char *ntlmchalresp, unsigned char p24[24])
232 { 265 {
233 unsigned char p21[21]; 266 unsigned char p21[21];
234 267
235 memset(p21, '\0', 21); 268 memset(p21, '\0', 21);
236 memcpy(p21, passwd, 8); 269 memcpy(p21, passwd, 8);
237 memset(p21 + 8, 0xbd, 8); 270 memset(p21 + 8, 0xbd, 8);
238 271
239 E_P24(p21, ntlmchalresp, p24); 272 E_P24(p21, ntlmchalresp, p24);
240 } 273 }
241 #endif 274 #endif
242 275
243 /* Does the NT MD4 hash then des encryption. */ 276 /* Does the NT MD4 hash then des encryption. */
244 277 int
245 void
246 SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) 278 SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
247 { 279 {
280 int rc;
248 unsigned char p21[21]; 281 unsigned char p21[21];
249 282
250 memset(p21, '\0', 21); 283 memset(p21, '\0', 21);
251 284
252 E_md4hash(passwd, p21); 285 rc = E_md4hash(passwd, p21);
286 if (rc) {
287 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
288 return rc;
289 }
253 SMBOWFencrypt(p21, c8, p24); 290 SMBOWFencrypt(p21, c8, p24);
291 return rc;
254 } 292 }
255 293
256 294
257 /* Does the md5 encryption from the NT hash for NTLMv2. */ 295 /* Does the md5 encryption from the NT hash for NTLMv2. */
258 /* These routines will be needed later */ 296 /* These routines will be needed later */
259 #if 0 297 #if 0
260 static void 298 static void
261 SMBOWFencrypt_ntv2(const unsigned char kr[16], 299 SMBOWFencrypt_ntv2(const unsigned char kr[16],
262 const struct data_blob *srv_chal, 300 const struct data_blob *srv_chal,
263 const struct data_blob *cli_chal, unsigned char resp_buf[16]) 301 const struct data_blob *cli_chal, unsigned char resp_buf[16])
264 { 302 {
265 struct HMACMD5Context ctx; 303 struct HMACMD5Context ctx;
266 304
267 hmac_md5_init_limK_to_64(kr, 16, &ctx); 305 hmac_md5_init_limK_to_64(kr, 16, &ctx);
268 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); 306 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
269 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); 307 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
270 hmac_md5_final(resp_buf, &ctx); 308 hmac_md5_final(resp_buf, &ctx);
271 } 309 }
272 310
273 static void 311 static void
274 SMBsesskeygen_ntv2(const unsigned char kr[16], 312 SMBsesskeygen_ntv2(const unsigned char kr[16],
275 const unsigned char *nt_resp, __u8 sess_key[16]) 313 const unsigned char *nt_resp, __u8 sess_key[16])
276 { 314 {
277 struct HMACMD5Context ctx; 315 struct HMACMD5Context ctx;