Blame view

fs/cifs/sess.c 28.4 KB
3979877e5   Steve French   [CIFS] Support fo...
1
2
3
4
5
  /*
   *   fs/cifs/sess.c
   *
   *   SMB/CIFS session setup handling routines
   *
d185cda77   Steve French   [CIFS] rename cif...
6
   *   Copyright (c) International Business Machines  Corp., 2006, 2009
3979877e5   Steve French   [CIFS] Support fo...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   This library is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU Lesser General Public License as published
   *   by the Free Software Foundation; either version 2.1 of the License, or
   *   (at your option) any later version.
   *
   *   This library is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
   *   the GNU Lesser General Public License for more details.
   *
   *   You should have received a copy of the GNU Lesser General Public License
   *   along with this library; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  
  #include "cifspdu.h"
  #include "cifsglob.h"
  #include "cifsproto.h"
  #include "cifs_unicode.h"
  #include "cifs_debug.h"
  #include "ntlmssp.h"
  #include "nterr.h"
9c53588ec   Steve French   [CIFS] Missing in...
31
  #include <linux/utsname.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
32
  #include <linux/slab.h>
2442421b1   Steve French   [CIFS] Have CIFS_...
33
  #include "cifs_spnego.h"
3979877e5   Steve French   [CIFS] Support fo...
34

ebe6aa5ac   Jeff Layton   cifs: eliminate "...
35
36
37
38
39
  /*
   * Checks if this is the first smb session to be reconnected after
   * the socket has been reestablished (so we know whether to use vc 0).
   * Called while holding the cifs_tcp_ses_lock, so do not block
   */
96daf2b09   Steve French   [CIFS] Rename thr...
40
  static bool is_first_ses_reconnect(struct cifs_ses *ses)
eca6acf91   Steve French   [CIFS] Fix multiu...
41
42
  {
  	struct list_head *tmp;
96daf2b09   Steve French   [CIFS] Rename thr...
43
  	struct cifs_ses *tmp_ses;
eca6acf91   Steve French   [CIFS] Fix multiu...
44
45
  
  	list_for_each(tmp, &ses->server->smb_ses_list) {
96daf2b09   Steve French   [CIFS] Rename thr...
46
  		tmp_ses = list_entry(tmp, struct cifs_ses,
eca6acf91   Steve French   [CIFS] Fix multiu...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  				     smb_ses_list);
  		if (tmp_ses->need_reconnect == false)
  			return false;
  	}
  	/* could not find a session that was already connected,
  	   this must be the first one we are reconnecting */
  	return true;
  }
  
  /*
   *	vc number 0 is treated specially by some servers, and should be the
   *      first one we request.  After that we can use vcnumbers up to maxvcs,
   *	one for each smb session (some Windows versions set maxvcs incorrectly
   *	so maxvc=1 can be ignored).  If we have too many vcs, we can reuse
   *	any vc but zero (some servers reset the connection on vcnum zero)
   *
   */
96daf2b09   Steve French   [CIFS] Rename thr...
64
  static __le16 get_next_vcnum(struct cifs_ses *ses)
eca6acf91   Steve French   [CIFS] Fix multiu...
65
66
67
  {
  	__u16 vcnum = 0;
  	struct list_head *tmp;
96daf2b09   Steve French   [CIFS] Rename thr...
68
  	struct cifs_ses *tmp_ses;
eca6acf91   Steve French   [CIFS] Fix multiu...
69
70
71
72
73
74
75
76
77
78
  	__u16 max_vcs = ses->server->max_vcs;
  	__u16 i;
  	int free_vc_found = 0;
  
  	/* Quoting the MS-SMB specification: "Windows-based SMB servers set this
  	field to one but do not enforce this limit, which allows an SMB client
  	to establish more virtual circuits than allowed by this value ... but
  	other server implementations can enforce this limit." */
  	if (max_vcs < 2)
  		max_vcs = 0xFFFF;
3f9bcca78   Suresh Jayaraman   cifs: convert cif...
79
  	spin_lock(&cifs_tcp_ses_lock);
eca6acf91   Steve French   [CIFS] Fix multiu...
80
81
82
83
84
85
86
87
88
  	if ((ses->need_reconnect) && is_first_ses_reconnect(ses))
  			goto get_vc_num_exit;  /* vcnum will be zero */
  	for (i = ses->server->srv_count - 1; i < max_vcs; i++) {
  		if (i == 0) /* this is the only connection, use vc 0 */
  			break;
  
  		free_vc_found = 1;
  
  		list_for_each(tmp, &ses->server->smb_ses_list) {
96daf2b09   Steve French   [CIFS] Rename thr...
89
  			tmp_ses = list_entry(tmp, struct cifs_ses,
eca6acf91   Steve French   [CIFS] Fix multiu...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  					     smb_ses_list);
  			if (tmp_ses->vcnum == i) {
  				free_vc_found = 0;
  				break; /* found duplicate, try next vcnum */
  			}
  		}
  		if (free_vc_found)
  			break; /* we found a vcnumber that will work - use it */
  	}
  
  	if (i == 0)
  		vcnum = 0; /* for most common case, ie if one smb session, use
  			      vc zero.  Also for case when no free vcnum, zero
  			      is safest to send (some clients only send zero) */
  	else if (free_vc_found == 0)
  		vcnum = 1;  /* we can not reuse vc=0 safely, since some servers
  				reset all uids on that, but 1 is ok. */
  	else
  		vcnum = i;
  	ses->vcnum = vcnum;
  get_vc_num_exit:
3f9bcca78   Suresh Jayaraman   cifs: convert cif...
111
  	spin_unlock(&cifs_tcp_ses_lock);
eca6acf91   Steve French   [CIFS] Fix multiu...
112

051a2a0d3   Steve French   [CIFS] Fix endian...
113
  	return cpu_to_le16(vcnum);
eca6acf91   Steve French   [CIFS] Fix multiu...
114
  }
96daf2b09   Steve French   [CIFS] Rename thr...
115
  static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
3979877e5   Steve French   [CIFS] Support fo...
116
117
118
119
  {
  	__u32 capabilities = 0;
  
  	/* init fields common to all four types of SessSetup */
eca6acf91   Steve French   [CIFS] Fix multiu...
120
121
122
123
  	/* Note that offsets for first seven fields in req struct are same  */
  	/*	in CIFS Specs so does not matter which of 3 forms of struct */
  	/*	that we use in next few lines                               */
  	/* Note that header is initialized to zero in header_assemble */
3979877e5   Steve French   [CIFS] Support fo...
124
  	pSMB->req.AndXCommand = 0xFF;
c974befa4   Jeff Layton   cifs: untangle se...
125
126
127
  	pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
  					CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
  					USHRT_MAX));
3979877e5   Steve French   [CIFS] Support fo...
128
  	pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
eca6acf91   Steve French   [CIFS] Fix multiu...
129
  	pSMB->req.VcNumber = get_next_vcnum(ses);
3979877e5   Steve French   [CIFS] Support fo...
130
131
  
  	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
790fe579f   Steve French   [CIFS] more white...
132
  	/* BB verify whether signing required on neg or just on auth frame
3979877e5   Steve French   [CIFS] Support fo...
133
134
135
136
  	   (and NTLM case) */
  
  	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
  			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
96daf2b09   Steve French   [CIFS] Rename thr...
137
  	if (ses->server->sec_mode &
790fe579f   Steve French   [CIFS] more white...
138
  	    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3979877e5   Steve French   [CIFS] Support fo...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
  
  	if (ses->capabilities & CAP_UNICODE) {
  		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
  		capabilities |= CAP_UNICODE;
  	}
  	if (ses->capabilities & CAP_STATUS32) {
  		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
  		capabilities |= CAP_STATUS32;
  	}
  	if (ses->capabilities & CAP_DFS) {
  		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
  		capabilities |= CAP_DFS;
  	}
26f57364d   Steve French   [CIFS] formatting...
153
  	if (ses->capabilities & CAP_UNIX)
3979877e5   Steve French   [CIFS] Support fo...
154
  		capabilities |= CAP_UNIX;
3979877e5   Steve French   [CIFS] Support fo...
155

3979877e5   Steve French   [CIFS] Support fo...
156
157
  	return capabilities;
  }
0d3a01fad   Jeff Layton   [CIFS] Break up u...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  static void
  unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
  {
  	char *bcc_ptr = *pbcc_area;
  	int bytes_ret = 0;
  
  	/* Copy OS version */
  	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
  				  nls_cp);
  	bcc_ptr += 2 * bytes_ret;
  	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
  				  32, nls_cp);
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2; /* trailing null */
  
  	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
  				  32, nls_cp);
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2; /* trailing null */
  
  	*pbcc_area = bcc_ptr;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
180
  static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
0d3a01fad   Jeff Layton   [CIFS] Break up u...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  				   const struct nls_table *nls_cp)
  {
  	char *bcc_ptr = *pbcc_area;
  	int bytes_ret = 0;
  
  	/* copy domain */
  	if (ses->domainName == NULL) {
  		/* Sending null domain better than using a bogus domain name (as
  		we did briefly in 2.6.18) since server will use its default */
  		*bcc_ptr = 0;
  		*(bcc_ptr+1) = 0;
  		bytes_ret = 0;
  	} else
  		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
  					  256, nls_cp);
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2;  /* account for null terminator */
  
  	*pbcc_area = bcc_ptr;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
201
  static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
790fe579f   Steve French   [CIFS] more white...
202
  				   const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
203
  {
790fe579f   Steve French   [CIFS] more white...
204
  	char *bcc_ptr = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
205
206
207
208
  	int bytes_ret = 0;
  
  	/* BB FIXME add check that strings total less
  	than 335 or will need to send them as arrays */
0223cf0b1   Steve French   [CIFS] Fix alignm...
209
210
  	/* unicode strings, must be word aligned before the call */
  /*	if ((long) bcc_ptr % 2)	{
3979877e5   Steve French   [CIFS] Support fo...
211
212
  		*bcc_ptr = 0;
  		bcc_ptr++;
0223cf0b1   Steve French   [CIFS] Fix alignm...
213
  	} */
3979877e5   Steve French   [CIFS] Support fo...
214
  	/* copy user */
8727c8a85   Steve French   Allow user names ...
215
  	if (ses->user_name == NULL) {
6e659c639   Steve French   [CIFS] Fix mount...
216
217
218
  		/* null user mount */
  		*bcc_ptr = 0;
  		*(bcc_ptr+1) = 0;
301a6a317   Steve French   [CIFS] Maximum us...
219
  	} else {
8727c8a85   Steve French   Allow user names ...
220
  		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->user_name,
301a6a317   Steve French   [CIFS] Maximum us...
221
  					  MAX_USERNAME_SIZE, nls_cp);
3979877e5   Steve French   [CIFS] Support fo...
222
223
224
  	}
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2; /* account for null termination */
3979877e5   Steve French   [CIFS] Support fo...
225

0d3a01fad   Jeff Layton   [CIFS] Break up u...
226
227
  	unicode_domain_string(&bcc_ptr, ses, nls_cp);
  	unicode_oslm_strings(&bcc_ptr, nls_cp);
3979877e5   Steve French   [CIFS] Support fo...
228
229
230
  
  	*pbcc_area = bcc_ptr;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
231
  static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
790fe579f   Steve French   [CIFS] more white...
232
  				 const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
233
  {
790fe579f   Steve French   [CIFS] more white...
234
  	char *bcc_ptr = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
235
236
237
  
  	/* copy user */
  	/* BB what about null user mounts - check that we do this BB */
790fe579f   Steve French   [CIFS] more white...
238
  	/* copy user */
8727c8a85   Steve French   Allow user names ...
239
240
241
242
243
  	if (ses->user_name != NULL)
  		strncpy(bcc_ptr, ses->user_name, MAX_USERNAME_SIZE);
  	/* else null user mount */
  
  	bcc_ptr += strnlen(ses->user_name, MAX_USERNAME_SIZE);
3979877e5   Steve French   [CIFS] Support fo...
244
  	*bcc_ptr = 0;
790fe579f   Steve French   [CIFS] more white...
245
  	bcc_ptr++; /* account for null termination */
3979877e5   Steve French   [CIFS] Support fo...
246

790fe579f   Steve French   [CIFS] more white...
247
248
249
250
  	/* copy domain */
  
  	if (ses->domainName != NULL) {
  		strncpy(bcc_ptr, ses->domainName, 256);
3979877e5   Steve French   [CIFS] Support fo...
251
  		bcc_ptr += strnlen(ses->domainName, 256);
790fe579f   Steve French   [CIFS] more white...
252
  	} /* else we will send a null domain name
6e659c639   Steve French   [CIFS] Fix mount...
253
  	     so the server will default to its own domain */
3979877e5   Steve French   [CIFS] Support fo...
254
255
256
257
258
259
260
  	*bcc_ptr = 0;
  	bcc_ptr++;
  
  	/* BB check for overflow here */
  
  	strcpy(bcc_ptr, "Linux version ");
  	bcc_ptr += strlen("Linux version ");
96b644bde   Serge E. Hallyn   [PATCH] namespace...
261
262
  	strcpy(bcc_ptr, init_utsname()->release);
  	bcc_ptr += strlen(init_utsname()->release) + 1;
3979877e5   Steve French   [CIFS] Support fo...
263
264
265
  
  	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
  	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
790fe579f   Steve French   [CIFS] more white...
266
  	*pbcc_area = bcc_ptr;
3979877e5   Steve French   [CIFS] Support fo...
267
  }
59140797c   Jeff Layton   cifs: fix session...
268
  static void
96daf2b09   Steve French   [CIFS] Rename thr...
269
  decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
59140797c   Jeff Layton   cifs: fix session...
270
  		      const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
271
  {
59140797c   Jeff Layton   cifs: fix session...
272
  	int len;
790fe579f   Steve French   [CIFS] more white...
273
  	char *data = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
274

b6b38f704   Joe Perches   [CIFS] Neaten cER...
275
  	cFYI(1, "bleft %d", bleft);
3979877e5   Steve French   [CIFS] Support fo...
276

26f57364d   Steve French   [CIFS] formatting...
277
  	kfree(ses->serverOS);
d185cda77   Steve French   [CIFS] rename cif...
278
  	ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
279
  	cFYI(1, "serverOS=%s", ses->serverOS);
59140797c   Jeff Layton   cifs: fix session...
280
281
282
283
284
  	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
  	data += len;
  	bleft -= len;
  	if (bleft <= 0)
  		return;
3979877e5   Steve French   [CIFS] Support fo...
285

26f57364d   Steve French   [CIFS] formatting...
286
  	kfree(ses->serverNOS);
d185cda77   Steve French   [CIFS] rename cif...
287
  	ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
288
  	cFYI(1, "serverNOS=%s", ses->serverNOS);
59140797c   Jeff Layton   cifs: fix session...
289
290
291
292
293
  	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
  	data += len;
  	bleft -= len;
  	if (bleft <= 0)
  		return;
790fe579f   Steve French   [CIFS] more white...
294

26f57364d   Steve French   [CIFS] formatting...
295
  	kfree(ses->serverDomain);
d185cda77   Steve French   [CIFS] rename cif...
296
  	ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
297
  	cFYI(1, "serverDomain=%s", ses->serverDomain);
790fe579f   Steve French   [CIFS] more white...
298

59140797c   Jeff Layton   cifs: fix session...
299
  	return;
3979877e5   Steve French   [CIFS] Support fo...
300
  }
690c522fa   Jeff Layton   cifs: use get/put...
301
  static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
96daf2b09   Steve French   [CIFS] Rename thr...
302
  			       struct cifs_ses *ses,
790fe579f   Steve French   [CIFS] more white...
303
  			       const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
304
305
306
  {
  	int rc = 0;
  	int len;
790fe579f   Steve French   [CIFS] more white...
307
  	char *bcc_ptr = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
308

b6b38f704   Joe Perches   [CIFS] Neaten cER...
309
  	cFYI(1, "decode sessetup ascii. bleft %d", bleft);
50c2f7538   Steve French   [CIFS] whitespace...
310

3979877e5   Steve French   [CIFS] Support fo...
311
  	len = strnlen(bcc_ptr, bleft);
790fe579f   Steve French   [CIFS] more white...
312
  	if (len >= bleft)
3979877e5   Steve French   [CIFS] Support fo...
313
  		return rc;
50c2f7538   Steve French   [CIFS] whitespace...
314

26f57364d   Steve French   [CIFS] formatting...
315
  	kfree(ses->serverOS);
3979877e5   Steve French   [CIFS] Support fo...
316
317
  
  	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
790fe579f   Steve French   [CIFS] more white...
318
  	if (ses->serverOS)
3979877e5   Steve French   [CIFS] Support fo...
319
  		strncpy(ses->serverOS, bcc_ptr, len);
790fe579f   Steve French   [CIFS] more white...
320
  	if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
321
  			cFYI(1, "OS/2 server");
9ac00b7d9   Steve French   [CIFS] Do not sen...
322
323
  			ses->flags |= CIFS_SES_OS2;
  	}
3979877e5   Steve French   [CIFS] Support fo...
324
325
326
327
328
  
  	bcc_ptr += len + 1;
  	bleft -= len + 1;
  
  	len = strnlen(bcc_ptr, bleft);
790fe579f   Steve French   [CIFS] more white...
329
  	if (len >= bleft)
3979877e5   Steve French   [CIFS] Support fo...
330
  		return rc;
26f57364d   Steve French   [CIFS] formatting...
331
  	kfree(ses->serverNOS);
3979877e5   Steve French   [CIFS] Support fo...
332
333
  
  	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
790fe579f   Steve French   [CIFS] more white...
334
  	if (ses->serverNOS)
3979877e5   Steve French   [CIFS] Support fo...
335
336
337
338
  		strncpy(ses->serverNOS, bcc_ptr, len);
  
  	bcc_ptr += len + 1;
  	bleft -= len + 1;
790fe579f   Steve French   [CIFS] more white...
339
340
341
  	len = strnlen(bcc_ptr, bleft);
  	if (len > bleft)
  		return rc;
3979877e5   Steve French   [CIFS] Support fo...
342

9ac00b7d9   Steve French   [CIFS] Do not sen...
343
344
345
346
347
  	/* No domain field in LANMAN case. Domain is
  	   returned by old servers in the SMB negprot response */
  	/* BB For newer servers which do not support Unicode,
  	   but thus do return domain here we could add parsing
  	   for it later, but it is not very important */
b6b38f704   Joe Perches   [CIFS] Neaten cER...
348
  	cFYI(1, "ascii: bytes left %d", bleft);
3979877e5   Steve French   [CIFS] Support fo...
349
350
351
  
  	return rc;
  }
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
352
  static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
96daf2b09   Steve French   [CIFS] Rename thr...
353
  				    struct cifs_ses *ses)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
354
  {
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
355
356
  	unsigned int tioffset; /* challenge message target info area */
  	unsigned int tilen; /* challenge message target info area length  */
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
357
358
359
  	CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
  
  	if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
360
  		cERROR(1, "challenge blob len %d too small", blob_len);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
361
362
363
364
  		return -EINVAL;
  	}
  
  	if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
365
  		cERROR(1, "blob signature incorrect %s", pblob->Signature);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
366
367
368
  		return -EINVAL;
  	}
  	if (pblob->MessageType != NtLmChallenge) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
369
  		cERROR(1, "Incorrect message type %d", pblob->MessageType);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
370
371
  		return -EINVAL;
  	}
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
372
  	memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
373
374
375
376
  	/* BB we could decode pblob->NegotiateFlags; some may be useful */
  	/* In particular we can examine sign flags */
  	/* BB spec says that if AvId field of MsvAvTimestamp is populated then
  		we must set the MIC field of the AUTHENTICATE_MESSAGE */
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
377
  	ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
5443d130a   Steve French   various endian fi...
378
379
  	tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
  	tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
380
381
382
  	if (tilen) {
  		ses->auth_key.response = kmalloc(tilen, GFP_KERNEL);
  		if (!ses->auth_key.response) {
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
383
  			cERROR(1, "Challenge target info allocation failure");
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
384
385
  			return -ENOMEM;
  		}
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
386
387
  		memcpy(ses->auth_key.response, bcc_ptr + tioffset, tilen);
  		ses->auth_key.len = tilen;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
388
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
389
390
  	return 0;
  }
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
391
392
393
394
395
  /* BB Move to ntlmssp.c eventually */
  
  /* We do not malloc the blob, it is passed in pbuffer, because
     it is fixed size, and small, making this approach cleaner */
  static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
96daf2b09   Steve French   [CIFS] Rename thr...
396
  					 struct cifs_ses *ses)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
397
398
399
  {
  	NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
  	__u32 flags;
df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
400
  	memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
401
402
403
404
405
406
  	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
  	sec_blob->MessageType = NtLmNegotiate;
  
  	/* BB is NTLMV2 session security format easier to use here? */
  	flags = NTLMSSP_NEGOTIATE_56 |	NTLMSSP_REQUEST_TARGET |
  		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
407
  		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
96daf2b09   Steve French   [CIFS] Rename thr...
408
  	if (ses->server->sec_mode &
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
409
  			(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
745e507a9   Steve French   Revert "missing c...
410
  		flags |= NTLMSSP_NEGOTIATE_SIGN;
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
411
  		if (!ses->server->session_estab)
62411ab2f   Shirish Pargaonkar   cifs: Fix signing...
412
  			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
413
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
414

df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
415
  	sec_blob->NegotiateFlags = cpu_to_le32(flags);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
  
  	sec_blob->WorkstationName.BufferOffset = 0;
  	sec_blob->WorkstationName.Length = 0;
  	sec_blob->WorkstationName.MaximumLength = 0;
  
  	/* Domain name is sent on the Challenge not Negotiate NTLMSSP request */
  	sec_blob->DomainName.BufferOffset = 0;
  	sec_blob->DomainName.Length = 0;
  	sec_blob->DomainName.MaximumLength = 0;
  }
  
  /* We do not malloc the blob, it is passed in pbuffer, because its
     maximum possible size is fixed and small, making this approach cleaner.
     This function returns the length of the data in the blob */
  static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
89f150f40   Shirish Pargaonkar   Clean up two decl...
431
  					u16 *buflen,
96daf2b09   Steve French   [CIFS] Rename thr...
432
  				   struct cifs_ses *ses,
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
433
  				   const struct nls_table *nls_cp)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
434
  {
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
435
  	int rc;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
436
437
438
  	AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
  	__u32 flags;
  	unsigned char *tmp;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
439
440
441
442
443
444
445
  
  	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
  	sec_blob->MessageType = NtLmAuthenticate;
  
  	flags = NTLMSSP_NEGOTIATE_56 |
  		NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
  		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
446
  		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
96daf2b09   Steve French   [CIFS] Rename thr...
447
  	if (ses->server->sec_mode &
62411ab2f   Shirish Pargaonkar   cifs: Fix signing...
448
  	   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
449
  		flags |= NTLMSSP_NEGOTIATE_SIGN;
62411ab2f   Shirish Pargaonkar   cifs: Fix signing...
450
451
452
  		if (!ses->server->session_estab)
  			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
453
454
  
  	tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
455
  	sec_blob->NegotiateFlags = cpu_to_le32(flags);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
456
457
458
459
460
  
  	sec_blob->LmChallengeResponse.BufferOffset =
  				cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
  	sec_blob->LmChallengeResponse.Length = 0;
  	sec_blob->LmChallengeResponse.MaximumLength = 0;
c8e56f1f4   Steve French   Revert "[CIFS] Fi...
461
  	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
462
  	rc = setup_ntlmv2_rsp(ses, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
463
464
465
466
  	if (rc) {
  		cERROR(1, "Error %d during NTLMSSP authentication", rc);
  		goto setup_ntlmv2_ret;
  	}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
467
468
469
  	memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
  			ses->auth_key.len - CIFS_SESS_KEY_SIZE);
  	tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
c8e56f1f4   Steve French   Revert "[CIFS] Fi...
470

21e733930   Shirish Pargaonkar   NTLM auth and sig...
471
472
  	sec_blob->NtChallengeResponse.Length =
  			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
473
  	sec_blob->NtChallengeResponse.MaximumLength =
21e733930   Shirish Pargaonkar   NTLM auth and sig...
474
  			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
475
476
477
478
479
480
481
482
483
484
485
  
  	if (ses->domainName == NULL) {
  		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
  		sec_blob->DomainName.Length = 0;
  		sec_blob->DomainName.MaximumLength = 0;
  		tmp += 2;
  	} else {
  		int len;
  		len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
  				    MAX_USERNAME_SIZE, nls_cp);
  		len *= 2; /* unicode is 2 bytes each */
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
486
487
488
489
490
  		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
  		sec_blob->DomainName.Length = cpu_to_le16(len);
  		sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
  		tmp += len;
  	}
8727c8a85   Steve French   Allow user names ...
491
  	if (ses->user_name == NULL) {
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
492
493
494
495
496
497
  		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
  		sec_blob->UserName.Length = 0;
  		sec_blob->UserName.MaximumLength = 0;
  		tmp += 2;
  	} else {
  		int len;
8727c8a85   Steve French   Allow user names ...
498
  		len = cifs_strtoUCS((__le16 *)tmp, ses->user_name,
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
499
500
  				    MAX_USERNAME_SIZE, nls_cp);
  		len *= 2; /* unicode is 2 bytes each */
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
501
502
503
504
505
506
507
508
509
510
  		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
  		sec_blob->UserName.Length = cpu_to_le16(len);
  		sec_blob->UserName.MaximumLength = cpu_to_le16(len);
  		tmp += len;
  	}
  
  	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
  	sec_blob->WorkstationName.Length = 0;
  	sec_blob->WorkstationName.MaximumLength = 0;
  	tmp += 2;
df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
511
512
513
  	if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
  		(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
  			&& !calc_seckey(ses)) {
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
514
  		memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
515
516
517
518
519
520
521
522
523
524
  		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
  		sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
  		sec_blob->SessionKey.MaximumLength =
  				cpu_to_le16(CIFS_CPHTXT_SIZE);
  		tmp += CIFS_CPHTXT_SIZE;
  	} else {
  		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
  		sec_blob->SessionKey.Length = 0;
  		sec_blob->SessionKey.MaximumLength = 0;
  	}
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
525
526
  
  setup_ntlmv2_ret:
89f150f40   Shirish Pargaonkar   Clean up two decl...
527
528
  	*buflen = tmp - pbuffer;
  	return rc;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
529
  }
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
530

790fe579f   Steve French   [CIFS] more white...
531
  int
96daf2b09   Steve French   [CIFS] Rename thr...
532
  CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
ebe6aa5ac   Jeff Layton   cifs: eliminate "...
533
  	       const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
534
535
536
  {
  	int rc = 0;
  	int wct;
3979877e5   Steve French   [CIFS] Support fo...
537
538
  	struct smb_hdr *smb_buf;
  	char *bcc_ptr;
750d1151a   Steve French   [CIFS] Fix alloca...
539
  	char *str_area;
3979877e5   Steve French   [CIFS] Support fo...
540
541
  	SESSION_SETUP_ANDX *pSMB;
  	__u32 capabilities;
690c522fa   Jeff Layton   cifs: use get/put...
542
  	__u16 count;
2442421b1   Steve French   [CIFS] Have CIFS_...
543
544
  	int resp_buf_type;
  	struct kvec iov[3];
3979877e5   Steve French   [CIFS] Support fo...
545
  	enum securityEnum type;
690c522fa   Jeff Layton   cifs: use get/put...
546
  	__u16 action, bytes_remaining;
2442421b1   Steve French   [CIFS] Have CIFS_...
547
  	struct key *spnego_key = NULL;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
548
  	__le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
89f150f40   Shirish Pargaonkar   Clean up two decl...
549
  	u16 blob_len;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
550
  	char *ntlmsspblob = NULL;
254e55ed0   Steve French   CIFS] Support for...
551

790fe579f   Steve French   [CIFS] more white...
552
  	if (ses == NULL)
3979877e5   Steve French   [CIFS] Support fo...
553
554
555
  		return -EINVAL;
  
  	type = ses->server->secType;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
556
  	cFYI(1, "sess setup type %d", type);
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
557
558
559
560
561
562
563
564
  	if (type == RawNTLMSSP) {
  		/* if memory allocation is successful, caller of this function
  		 * frees it.
  		 */
  		ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
  		if (!ses->ntlmssp)
  			return -ENOMEM;
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
565
566
567
  ssetup_ntlmssp_authenticate:
  	if (phase == NtLmChallenge)
  		phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
790fe579f   Steve French   [CIFS] more white...
568
  	if (type == LANMAN) {
3979877e5   Steve French   [CIFS] Support fo...
569
570
571
572
573
574
575
576
577
  #ifndef CONFIG_CIFS_WEAK_PW_HASH
  		/* LANMAN and plaintext are less secure and off by default.
  		So we make this explicitly be turned on in kconfig (in the
  		build) and turned on at runtime (changed from the default)
  		in proc/fs/cifs or via mount parm.  Unfortunately this is
  		needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
  		return -EOPNOTSUPP;
  #endif
  		wct = 10; /* lanman 2 style sessionsetup */
790fe579f   Steve French   [CIFS] more white...
578
  	} else if ((type == NTLM) || (type == NTLMv2)) {
9312f6754   Steve French   [CIFS] Fix mask s...
579
  		/* For NTLMv2 failures eventually may need to retry NTLM */
3979877e5   Steve French   [CIFS] Support fo...
580
  		wct = 13; /* old style NTLM sessionsetup */
790fe579f   Steve French   [CIFS] more white...
581
  	} else /* same size: negotiate or auth, NTLMSSP or extended security */
3979877e5   Steve French   [CIFS] Support fo...
582
583
584
585
  		wct = 12;
  
  	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
  			    (void **)&smb_buf);
790fe579f   Steve French   [CIFS] more white...
586
  	if (rc)
3979877e5   Steve French   [CIFS] Support fo...
587
588
589
590
591
  		return rc;
  
  	pSMB = (SESSION_SETUP_ANDX *)smb_buf;
  
  	capabilities = cifs_ssetup_hdr(ses, pSMB);
750d1151a   Steve French   [CIFS] Fix alloca...
592

2442421b1   Steve French   [CIFS] Have CIFS_...
593
594
595
596
597
598
  	/* we will send the SMB in three pieces:
  	a fixed length beginning part, an optional
  	SPNEGO blob (which can be zero length), and a
  	last part which will include the strings
  	and rest of bcc area. This allows us to avoid
  	a large buffer 17K allocation */
790fe579f   Steve French   [CIFS] more white...
599
  	iov[0].iov_base = (char *)pSMB;
be8e3b004   Steve French   consistently use ...
600
  	iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
750d1151a   Steve French   [CIFS] Fix alloca...
601

2442421b1   Steve French   [CIFS] Have CIFS_...
602
603
604
  	/* setting this here allows the code at the end of the function
  	   to free the request buffer if there's an error */
  	resp_buf_type = CIFS_SMALL_BUFFER;
750d1151a   Steve French   [CIFS] Fix alloca...
605
606
  	/* 2000 big enough to fit max user, domain, NOS name etc. */
  	str_area = kmalloc(2000, GFP_KERNEL);
5e6e62327   Cyrill Gorcunov   [CIFS] Check retu...
607
  	if (str_area == NULL) {
2442421b1   Steve French   [CIFS] Have CIFS_...
608
609
  		rc = -ENOMEM;
  		goto ssetup_exit;
5e6e62327   Cyrill Gorcunov   [CIFS] Check retu...
610
  	}
750d1151a   Steve French   [CIFS] Fix alloca...
611
  	bcc_ptr = str_area;
3979877e5   Steve French   [CIFS] Support fo...
612

9ac00b7d9   Steve French   [CIFS] Do not sen...
613
  	ses->flags &= ~CIFS_SES_LANMAN;
2442421b1   Steve French   [CIFS] Have CIFS_...
614
615
  	iov[1].iov_base = NULL;
  	iov[1].iov_len = 0;
790fe579f   Steve French   [CIFS] more white...
616
  	if (type == LANMAN) {
3979877e5   Steve French   [CIFS] Support fo...
617
  #ifdef CONFIG_CIFS_WEAK_PW_HASH
5e640927a   Shirish Pargaonkar   cifs: Fix regress...
618
  		char lnm_session_key[CIFS_AUTH_RESP_SIZE];
3979877e5   Steve French   [CIFS] Support fo...
619

c76da9da1   Steve French   [CIFS] Turn off U...
620
  		pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
3979877e5   Steve French   [CIFS] Support fo...
621
  		/* no capabilities flags in old lanman negotiation */
5e640927a   Shirish Pargaonkar   cifs: Fix regress...
622
  		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
3979877e5   Steve French   [CIFS] Support fo...
623

d3ba50b17   Shirish Pargaonkar   NTLM auth and sig...
624
625
626
627
628
  		/* Calculate hash with password and copy into bcc_ptr.
  		 * Encryption Key (stored as in cryptkey) gets used if the
  		 * security mode bit in Negottiate Protocol response states
  		 * to use challenge/response method (i.e. Password bit is 1).
  		 */
43988d768   Steve French   [CIFS] Use ecb de...
629
  		rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
96daf2b09   Steve French   [CIFS] Rename thr...
630
  				 ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
4e53a3fb9   Jeff Layton   cifs: have calc_l...
631
  					true : false, lnm_session_key);
790fe579f   Steve French   [CIFS] more white...
632
  		ses->flags |= CIFS_SES_LANMAN;
5e640927a   Shirish Pargaonkar   cifs: Fix regress...
633
634
  		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
  		bcc_ptr += CIFS_AUTH_RESP_SIZE;
3979877e5   Steve French   [CIFS] Support fo...
635
636
637
638
639
  
  		/* can not sign if LANMAN negotiated so no need
  		to calculate signing key? but what if server
  		changed to do higher than lanman dialect and
  		we reconnected would we ever calc signing_key? */
b6b38f704   Joe Perches   [CIFS] Neaten cER...
640
  		cFYI(1, "Negotiating LANMAN setting up strings");
3979877e5   Steve French   [CIFS] Support fo...
641
642
  		/* Unicode not allowed for LANMAN dialects */
  		ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
790fe579f   Steve French   [CIFS] more white...
643
  #endif
3979877e5   Steve French   [CIFS] Support fo...
644
  	} else if (type == NTLM) {
3979877e5   Steve French   [CIFS] Support fo...
645
646
  		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
  		pSMB->req_no_secext.CaseInsensitivePasswordLength =
21e733930   Shirish Pargaonkar   NTLM auth and sig...
647
  			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
3979877e5   Steve French   [CIFS] Support fo...
648
  		pSMB->req_no_secext.CaseSensitivePasswordLength =
21e733930   Shirish Pargaonkar   NTLM auth and sig...
649
650
651
  			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
  
  		/* calculate ntlm response and session key */
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
652
  		rc = setup_ntlm_response(ses, nls_cp);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
653
654
655
656
  		if (rc) {
  			cERROR(1, "Error %d during NTLM authentication", rc);
  			goto ssetup_exit;
  		}
50c2f7538   Steve French   [CIFS] whitespace...
657

21e733930   Shirish Pargaonkar   NTLM auth and sig...
658
659
660
661
662
663
664
  		/* copy ntlm response */
  		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
  				CIFS_AUTH_RESP_SIZE);
  		bcc_ptr += CIFS_AUTH_RESP_SIZE;
  		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
  				CIFS_AUTH_RESP_SIZE);
  		bcc_ptr += CIFS_AUTH_RESP_SIZE;
3979877e5   Steve French   [CIFS] Support fo...
665

790fe579f   Steve French   [CIFS] more white...
666
  		if (ses->capabilities & CAP_UNICODE) {
0223cf0b1   Steve French   [CIFS] Fix alignm...
667
668
669
  			/* unicode strings must be word aligned */
  			if (iov[0].iov_len % 2) {
  				*bcc_ptr = 0;
790fe579f   Steve French   [CIFS] more white...
670
671
  				bcc_ptr++;
  			}
7c7b25bc8   Steve French   [CIFS] Support fo...
672
  			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b1   Steve French   [CIFS] Fix alignm...
673
  		} else
7c7b25bc8   Steve French   [CIFS] Support fo...
674
675
  			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
  	} else if (type == NTLMv2) {
7c7b25bc8   Steve French   [CIFS] Support fo...
676
677
678
679
  		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
  
  		/* LM2 password would be here if we supported it */
  		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
7c7b25bc8   Steve French   [CIFS] Support fo...
680

21e733930   Shirish Pargaonkar   NTLM auth and sig...
681
682
  		/* calculate nlmv2 response and session key */
  		rc = setup_ntlmv2_rsp(ses, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
683
684
  		if (rc) {
  			cERROR(1, "Error %d during NTLMv2 authentication", rc);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
685
686
  			goto ssetup_exit;
  		}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
687
688
689
  		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
  				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
  		bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
c9928f704   Shirish Pargaonkar   ntlm authenticati...
690
691
692
693
  		/* set case sensitive password length after tilen may get
  		 * assigned, tilen is 0 otherwise.
  		 */
  		pSMB->req_no_secext.CaseSensitivePasswordLength =
f7c5445a9   Shirish Pargaonkar   NTLM auth and sig...
694
  			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
c9928f704   Shirish Pargaonkar   ntlm authenticati...
695

790fe579f   Steve French   [CIFS] more white...
696
697
  		if (ses->capabilities & CAP_UNICODE) {
  			if (iov[0].iov_len % 2) {
0223cf0b1   Steve French   [CIFS] Fix alignm...
698
  				*bcc_ptr = 0;
26f57364d   Steve French   [CIFS] formatting...
699
700
  				bcc_ptr++;
  			}
3979877e5   Steve French   [CIFS] Support fo...
701
  			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b1   Steve French   [CIFS] Fix alignm...
702
  		} else
3979877e5   Steve French   [CIFS] Support fo...
703
  			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
26efa0bac   Jeff Layton   cifs: have decode...
704
  	} else if (type == Kerberos) {
2442421b1   Steve French   [CIFS] Have CIFS_...
705
706
  #ifdef CONFIG_CIFS_UPCALL
  		struct cifs_spnego_msg *msg;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
707

2442421b1   Steve French   [CIFS] Have CIFS_...
708
709
710
711
712
713
714
715
  		spnego_key = cifs_get_spnego_key(ses);
  		if (IS_ERR(spnego_key)) {
  			rc = PTR_ERR(spnego_key);
  			spnego_key = NULL;
  			goto ssetup_exit;
  		}
  
  		msg = spnego_key->payload.data;
6ce5eecb9   Steve French   [CIFS] check vers...
716
717
718
  		/* check version field to make sure that cifs.upcall is
  		   sending us a response in an expected form */
  		if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
719
  			cERROR(1, "incorrect version of cifs.upcall (expected"
6ce5eecb9   Steve French   [CIFS] check vers...
720
  				   " %d but got %d)",
b6b38f704   Joe Perches   [CIFS] Neaten cER...
721
  				   CIFS_SPNEGO_UPCALL_VERSION, msg->version);
6ce5eecb9   Steve French   [CIFS] check vers...
722
723
724
  			rc = -EKEYREJECTED;
  			goto ssetup_exit;
  		}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
725
726
727
728
729
730
  
  		ses->auth_key.response = kmalloc(msg->sesskey_len, GFP_KERNEL);
  		if (!ses->auth_key.response) {
  			cERROR(1, "Kerberos can't allocate (%u bytes) memory",
  					msg->sesskey_len);
  			rc = -ENOMEM;
2442421b1   Steve French   [CIFS] Have CIFS_...
731
732
  			goto ssetup_exit;
  		}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
733
  		memcpy(ses->auth_key.response, msg->data, msg->sesskey_len);
5d0d28824   Shirish Pargaonkar   NTLM authenticati...
734
  		ses->auth_key.len = msg->sesskey_len;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
735

3979877e5   Steve French   [CIFS] Support fo...
736
737
738
  		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
  		capabilities |= CAP_EXTENDED_SECURITY;
  		pSMB->req.Capabilities = cpu_to_le32(capabilities);
2442421b1   Steve French   [CIFS] Have CIFS_...
739
740
741
742
743
744
  		iov[1].iov_base = msg->data + msg->sesskey_len;
  		iov[1].iov_len = msg->secblob_len;
  		pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);
  
  		if (ses->capabilities & CAP_UNICODE) {
  			/* unicode strings must be word aligned */
28c5a02a1   Jeff Layton   [CIFS] fix unico...
745
  			if ((iov[0].iov_len + iov[1].iov_len) % 2) {
2442421b1   Steve French   [CIFS] Have CIFS_...
746
747
748
749
750
751
752
753
754
  				*bcc_ptr = 0;
  				bcc_ptr++;
  			}
  			unicode_oslm_strings(&bcc_ptr, nls_cp);
  			unicode_domain_string(&bcc_ptr, ses, nls_cp);
  		} else
  		/* BB: is this right? */
  			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
  #else /* ! CONFIG_CIFS_UPCALL */
b6b38f704   Joe Perches   [CIFS] Neaten cER...
755
  		cERROR(1, "Kerberos negotiated but upcall support disabled!");
2442421b1   Steve French   [CIFS] Have CIFS_...
756
757
758
  		rc = -ENOSYS;
  		goto ssetup_exit;
  #endif /* CONFIG_CIFS_UPCALL */
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  	} else if (type == RawNTLMSSP) {
  		if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
  			cERROR(1, "NTLMSSP requires Unicode support");
  			rc = -ENOSYS;
  			goto ssetup_exit;
  		}
  
  		cFYI(1, "ntlmssp session setup phase %d", phase);
  		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
  		capabilities |= CAP_EXTENDED_SECURITY;
  		pSMB->req.Capabilities |= cpu_to_le32(capabilities);
  		switch(phase) {
  		case NtLmNegotiate:
  			build_ntlmssp_negotiate_blob(
  				pSMB->req.SecurityBlob, ses);
  			iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
  			iov[1].iov_base = pSMB->req.SecurityBlob;
  			pSMB->req.SecurityBlobLength =
  				cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
  			break;
  		case NtLmAuthenticate:
  			/*
  			 * 5 is an empirical value, large enough to hold
  			 * authenticate message plus max 10 of av paris,
  			 * domain, user, workstation names, flags, etc.
  			 */
  			ntlmsspblob = kzalloc(
  				5*sizeof(struct _AUTHENTICATE_MESSAGE),
  				GFP_KERNEL);
  			if (!ntlmsspblob) {
  				cERROR(1, "Can't allocate NTLMSSP blob");
  				rc = -ENOMEM;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
791
792
  				goto ssetup_exit;
  			}
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
793
794
795
  			rc = build_ntlmssp_auth_blob(ntlmsspblob,
  						&blob_len, ses, nls_cp);
  			if (rc)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
796
  				goto ssetup_exit;
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
797
798
799
800
801
802
803
804
805
806
807
808
  			iov[1].iov_len = blob_len;
  			iov[1].iov_base = ntlmsspblob;
  			pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
  			/*
  			 * Make sure that we tell the server that we are using
  			 * the uid that it just gave us back on the response
  			 * (challenge)
  			 */
  			smb_buf->Uid = ses->Suid;
  			break;
  		default:
  			cERROR(1, "invalid phase %d", phase);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
809
810
811
  			rc = -ENOSYS;
  			goto ssetup_exit;
  		}
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
812
813
814
815
816
817
818
  		/* unicode strings must be word aligned */
  		if ((iov[0].iov_len + iov[1].iov_len) % 2) {
  			*bcc_ptr = 0;
  			bcc_ptr++;
  		}
  		unicode_oslm_strings(&bcc_ptr, nls_cp);
  	} else {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
819
  		cERROR(1, "secType %d not supported!", type);
2442421b1   Steve French   [CIFS] Have CIFS_...
820
821
  		rc = -ENOSYS;
  		goto ssetup_exit;
3979877e5   Steve French   [CIFS] Support fo...
822
  	}
2442421b1   Steve French   [CIFS] Have CIFS_...
823
824
825
826
  	iov[2].iov_base = str_area;
  	iov[2].iov_len = (long) bcc_ptr - (long) str_area;
  
  	count = iov[1].iov_len + iov[2].iov_len;
be8e3b004   Steve French   consistently use ...
827
828
  	smb_buf->smb_buf_length =
  		cpu_to_be32(be32_to_cpu(smb_buf->smb_buf_length) + count);
3979877e5   Steve French   [CIFS] Support fo...
829

820a803ff   Jeff Layton   cifs: keep BCC in...
830
  	put_bcc(count, smb_buf);
3979877e5   Steve French   [CIFS] Support fo...
831

2442421b1   Steve French   [CIFS] Have CIFS_...
832
  	rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
7749981ec   Jeff Layton   cifs: remove code...
833
  			  CIFS_LOG_ERROR);
3979877e5   Steve French   [CIFS] Support fo...
834
  	/* SMB request buf freed in SendReceive2 */
3979877e5   Steve French   [CIFS] Support fo...
835
836
  	pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
  	smb_buf = (struct smb_hdr *)iov[0].iov_base;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
837
838
839
  	if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
  			cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
  		if (phase != NtLmNegotiate) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
840
  			cERROR(1, "Unexpected more processing error");
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
841
842
843
844
845
846
847
848
  			goto ssetup_exit;
  		}
  		/* NTLMSSP Negotiate sent now processing challenge (response) */
  		phase = NtLmChallenge; /* process ntlmssp challenge */
  		rc = 0; /* MORE_PROC rc is not an error here, but expected */
  	}
  	if (rc)
  		goto ssetup_exit;
790fe579f   Steve French   [CIFS] more white...
849
  	if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
3979877e5   Steve French   [CIFS] Support fo...
850
  		rc = -EIO;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
851
  		cERROR(1, "bad word count %d", smb_buf->WordCount);
3979877e5   Steve French   [CIFS] Support fo...
852
853
854
855
  		goto ssetup_exit;
  	}
  	action = le16_to_cpu(pSMB->resp.Action);
  	if (action & GUEST_LOGIN)
b6b38f704   Joe Perches   [CIFS] Neaten cER...
856
  		cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
3979877e5   Steve French   [CIFS] Support fo...
857
  	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
b6b38f704   Joe Perches   [CIFS] Neaten cER...
858
  	cFYI(1, "UID = %d ", ses->Suid);
3979877e5   Steve French   [CIFS] Support fo...
859
860
  	/* response can have either 3 or 4 word count - Samba sends 3 */
  	/* and lanman response is 3 */
690c522fa   Jeff Layton   cifs: use get/put...
861
  	bytes_remaining = get_bcc(smb_buf);
3979877e5   Steve French   [CIFS] Support fo...
862
  	bcc_ptr = pByteArea(smb_buf);
790fe579f   Steve French   [CIFS] more white...
863
  	if (smb_buf->WordCount == 4) {
3979877e5   Steve French   [CIFS] Support fo...
864
  		blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
790fe579f   Steve French   [CIFS] more white...
865
  		if (blob_len > bytes_remaining) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
866
  			cERROR(1, "bad security blob length %d", blob_len);
3979877e5   Steve French   [CIFS] Support fo...
867
868
869
  			rc = -EINVAL;
  			goto ssetup_exit;
  		}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
870
871
872
873
874
875
876
  		if (phase == NtLmChallenge) {
  			rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
  			/* now goto beginning for ntlmssp authenticate phase */
  			if (rc)
  				goto ssetup_exit;
  		}
  		bcc_ptr += blob_len;
3979877e5   Steve French   [CIFS] Support fo...
877
  		bytes_remaining -= blob_len;
790fe579f   Steve French   [CIFS] more white...
878
  	}
3979877e5   Steve French   [CIFS] Support fo...
879
880
  
  	/* BB check if Unicode and decode strings */
fcda7f457   Jeff Layton   cifs: check for b...
881
882
883
  	if (bytes_remaining == 0) {
  		/* no string area to decode, do nothing */
  	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
27b87fe52   Jeff Layton   cifs: fix unicode...
884
885
886
887
888
  		/* unicode string area must be word-aligned */
  		if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
  			++bcc_ptr;
  			--bytes_remaining;
  		}
59140797c   Jeff Layton   cifs: fix session...
889
  		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
27b87fe52   Jeff Layton   cifs: fix unicode...
890
  	} else {
63135e088   Steve French   [CIFS] More white...
891
892
  		rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
  					 ses, nls_cp);
27b87fe52   Jeff Layton   cifs: fix unicode...
893
  	}
50c2f7538   Steve French   [CIFS] whitespace...
894

3979877e5   Steve French   [CIFS] Support fo...
895
  ssetup_exit:
dfd15c46a   Jeff Layton   cifs: explicitly ...
896
897
  	if (spnego_key) {
  		key_revoke(spnego_key);
2442421b1   Steve French   [CIFS] Have CIFS_...
898
  		key_put(spnego_key);
dfd15c46a   Jeff Layton   cifs: explicitly ...
899
  	}
750d1151a   Steve French   [CIFS] Fix alloca...
900
  	kfree(str_area);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
901
902
  	kfree(ntlmsspblob);
  	ntlmsspblob = NULL;
790fe579f   Steve French   [CIFS] more white...
903
  	if (resp_buf_type == CIFS_SMALL_BUFFER) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
904
  		cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
3979877e5   Steve French   [CIFS] Support fo...
905
  		cifs_small_buf_release(iov[0].iov_base);
790fe579f   Steve French   [CIFS] more white...
906
  	} else if (resp_buf_type == CIFS_LARGE_BUFFER)
3979877e5   Steve French   [CIFS] Support fo...
907
  		cifs_buf_release(iov[0].iov_base);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
908
909
910
  	/* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
  	if ((phase == NtLmChallenge) && (rc == 0))
  		goto ssetup_ntlmssp_authenticate;
3979877e5   Steve French   [CIFS] Support fo...
911
912
  	return rc;
  }