Blame view

fs/cifs/sess.c 28.2 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

96daf2b09   Steve French   [CIFS] Rename thr...
35
  static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
3979877e5   Steve French   [CIFS] Support fo...
36
37
38
39
  {
  	__u32 capabilities = 0;
  
  	/* init fields common to all four types of SessSetup */
eca6acf91   Steve French   [CIFS] Fix multiu...
40
41
42
43
  	/* 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...
44
  	pSMB->req.AndXCommand = 0xFF;
c974befa4   Jeff Layton   cifs: untangle se...
45
46
47
  	pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
  					CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
  					USHRT_MAX));
3979877e5   Steve French   [CIFS] Support fo...
48
  	pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
9ae6cf606   Jeff Layton   cifs: stop trying...
49
  	pSMB->req.VcNumber = __constant_cpu_to_le16(1);
3979877e5   Steve French   [CIFS] Support fo...
50
51
  
  	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
790fe579f   Steve French   [CIFS] more white...
52
  	/* BB verify whether signing required on neg or just on auth frame
3979877e5   Steve French   [CIFS] Support fo...
53
54
55
56
  	   (and NTLM case) */
  
  	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
  			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
38d77c50b   Jeff Layton   cifs: track the e...
57
  	if (ses->server->sign)
3979877e5   Steve French   [CIFS] Support fo...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  		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...
72
  	if (ses->capabilities & CAP_UNIX)
3979877e5   Steve French   [CIFS] Support fo...
73
  		capabilities |= CAP_UNIX;
3979877e5   Steve French   [CIFS] Support fo...
74

3979877e5   Steve French   [CIFS] Support fo...
75
76
  	return capabilities;
  }
0d3a01fad   Jeff Layton   [CIFS] Break up u...
77
78
79
80
81
82
83
  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 */
acbbb76a2   Steve French   CIFS: Rename *UCS...
84
85
  	bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
  				    nls_cp);
0d3a01fad   Jeff Layton   [CIFS] Break up u...
86
  	bcc_ptr += 2 * bytes_ret;
acbbb76a2   Steve French   CIFS: Rename *UCS...
87
88
  	bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
  				    32, nls_cp);
0d3a01fad   Jeff Layton   [CIFS] Break up u...
89
90
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2; /* trailing null */
acbbb76a2   Steve French   CIFS: Rename *UCS...
91
92
  	bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
  				    32, nls_cp);
0d3a01fad   Jeff Layton   [CIFS] Break up u...
93
94
95
96
97
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2; /* trailing null */
  
  	*pbcc_area = bcc_ptr;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
98
  static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
0d3a01fad   Jeff Layton   [CIFS] Break up u...
99
100
101
102
103
104
105
106
107
108
109
110
111
  				   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
acbbb76a2   Steve French   CIFS: Rename *UCS...
112
  		bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
057d6332b   Chen Gang   cifs: extend the ...
113
  					    CIFS_MAX_DOMAINNAME_LEN, nls_cp);
0d3a01fad   Jeff Layton   [CIFS] Break up u...
114
115
116
117
118
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2;  /* account for null terminator */
  
  	*pbcc_area = bcc_ptr;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
119
  static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
790fe579f   Steve French   [CIFS] more white...
120
  				   const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
121
  {
790fe579f   Steve French   [CIFS] more white...
122
  	char *bcc_ptr = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
123
124
125
126
  	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...
127
128
  	/* unicode strings, must be word aligned before the call */
  /*	if ((long) bcc_ptr % 2)	{
3979877e5   Steve French   [CIFS] Support fo...
129
130
  		*bcc_ptr = 0;
  		bcc_ptr++;
0223cf0b1   Steve French   [CIFS] Fix alignm...
131
  	} */
3979877e5   Steve French   [CIFS] Support fo...
132
  	/* copy user */
8727c8a85   Steve French   Allow user names ...
133
  	if (ses->user_name == NULL) {
6e659c639   Steve French   [CIFS] Fix mount...
134
135
136
  		/* null user mount */
  		*bcc_ptr = 0;
  		*(bcc_ptr+1) = 0;
301a6a317   Steve French   [CIFS] Maximum us...
137
  	} else {
acbbb76a2   Steve French   CIFS: Rename *UCS...
138
  		bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
8c3a2b4c4   Scott Lovenberg   cifs: Move string...
139
  					    CIFS_MAX_USERNAME_LEN, nls_cp);
3979877e5   Steve French   [CIFS] Support fo...
140
141
142
  	}
  	bcc_ptr += 2 * bytes_ret;
  	bcc_ptr += 2; /* account for null termination */
3979877e5   Steve French   [CIFS] Support fo...
143

0d3a01fad   Jeff Layton   [CIFS] Break up u...
144
145
  	unicode_domain_string(&bcc_ptr, ses, nls_cp);
  	unicode_oslm_strings(&bcc_ptr, nls_cp);
3979877e5   Steve French   [CIFS] Support fo...
146
147
148
  
  	*pbcc_area = bcc_ptr;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
149
  static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
790fe579f   Steve French   [CIFS] more white...
150
  				 const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
151
  {
790fe579f   Steve French   [CIFS] more white...
152
  	char *bcc_ptr = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
153
154
155
  
  	/* copy user */
  	/* BB what about null user mounts - check that we do this BB */
790fe579f   Steve French   [CIFS] more white...
156
  	/* copy user */
de47a4176   Shirish Pargaonkar   cifs: Fix oops in...
157
  	if (ses->user_name != NULL) {
8c3a2b4c4   Scott Lovenberg   cifs: Move string...
158
159
  		strncpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
  		bcc_ptr += strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
de47a4176   Shirish Pargaonkar   cifs: Fix oops in...
160
  	}
8727c8a85   Steve French   Allow user names ...
161
  	/* else null user mount */
3979877e5   Steve French   [CIFS] Support fo...
162
  	*bcc_ptr = 0;
790fe579f   Steve French   [CIFS] more white...
163
  	bcc_ptr++; /* account for null termination */
3979877e5   Steve French   [CIFS] Support fo...
164

790fe579f   Steve French   [CIFS] more white...
165
  	/* copy domain */
790fe579f   Steve French   [CIFS] more white...
166
  	if (ses->domainName != NULL) {
057d6332b   Chen Gang   cifs: extend the ...
167
168
  		strncpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
  		bcc_ptr += strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
790fe579f   Steve French   [CIFS] more white...
169
  	} /* else we will send a null domain name
6e659c639   Steve French   [CIFS] Fix mount...
170
  	     so the server will default to its own domain */
3979877e5   Steve French   [CIFS] Support fo...
171
172
173
174
175
176
177
  	*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...
178
179
  	strcpy(bcc_ptr, init_utsname()->release);
  	bcc_ptr += strlen(init_utsname()->release) + 1;
3979877e5   Steve French   [CIFS] Support fo...
180
181
182
  
  	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
  	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
790fe579f   Steve French   [CIFS] more white...
183
  	*pbcc_area = bcc_ptr;
3979877e5   Steve French   [CIFS] Support fo...
184
  }
59140797c   Jeff Layton   cifs: fix session...
185
  static void
96daf2b09   Steve French   [CIFS] Rename thr...
186
  decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
59140797c   Jeff Layton   cifs: fix session...
187
  		      const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
188
  {
59140797c   Jeff Layton   cifs: fix session...
189
  	int len;
790fe579f   Steve French   [CIFS] more white...
190
  	char *data = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
191

f96637be0   Joe Perches   [CIFS] cifs: Rena...
192
193
  	cifs_dbg(FYI, "bleft %d
  ", bleft);
3979877e5   Steve French   [CIFS] Support fo...
194

26f57364d   Steve French   [CIFS] formatting...
195
  	kfree(ses->serverOS);
acbbb76a2   Steve French   CIFS: Rename *UCS...
196
  	ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
f96637be0   Joe Perches   [CIFS] cifs: Rena...
197
198
  	cifs_dbg(FYI, "serverOS=%s
  ", ses->serverOS);
59140797c   Jeff Layton   cifs: fix session...
199
200
201
202
203
  	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
  	data += len;
  	bleft -= len;
  	if (bleft <= 0)
  		return;
3979877e5   Steve French   [CIFS] Support fo...
204

26f57364d   Steve French   [CIFS] formatting...
205
  	kfree(ses->serverNOS);
acbbb76a2   Steve French   CIFS: Rename *UCS...
206
  	ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
f96637be0   Joe Perches   [CIFS] cifs: Rena...
207
208
  	cifs_dbg(FYI, "serverNOS=%s
  ", ses->serverNOS);
59140797c   Jeff Layton   cifs: fix session...
209
210
211
212
213
  	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
  	data += len;
  	bleft -= len;
  	if (bleft <= 0)
  		return;
790fe579f   Steve French   [CIFS] more white...
214

26f57364d   Steve French   [CIFS] formatting...
215
  	kfree(ses->serverDomain);
acbbb76a2   Steve French   CIFS: Rename *UCS...
216
  	ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
f96637be0   Joe Perches   [CIFS] cifs: Rena...
217
218
  	cifs_dbg(FYI, "serverDomain=%s
  ", ses->serverDomain);
790fe579f   Steve French   [CIFS] more white...
219

59140797c   Jeff Layton   cifs: fix session...
220
  	return;
3979877e5   Steve French   [CIFS] Support fo...
221
  }
7d0664596   Jeff Layton   cifs: make decode...
222
223
224
  static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
  				struct cifs_ses *ses,
  				const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
225
  {
3979877e5   Steve French   [CIFS] Support fo...
226
  	int len;
790fe579f   Steve French   [CIFS] more white...
227
  	char *bcc_ptr = *pbcc_area;
3979877e5   Steve French   [CIFS] Support fo...
228

f96637be0   Joe Perches   [CIFS] cifs: Rena...
229
230
  	cifs_dbg(FYI, "decode sessetup ascii. bleft %d
  ", bleft);
50c2f7538   Steve French   [CIFS] whitespace...
231

3979877e5   Steve French   [CIFS] Support fo...
232
  	len = strnlen(bcc_ptr, bleft);
790fe579f   Steve French   [CIFS] more white...
233
  	if (len >= bleft)
7d0664596   Jeff Layton   cifs: make decode...
234
  		return;
50c2f7538   Steve French   [CIFS] whitespace...
235

26f57364d   Steve French   [CIFS] formatting...
236
  	kfree(ses->serverOS);
3979877e5   Steve French   [CIFS] Support fo...
237
238
  
  	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
790fe579f   Steve French   [CIFS] more white...
239
  	if (ses->serverOS)
3979877e5   Steve French   [CIFS] Support fo...
240
  		strncpy(ses->serverOS, bcc_ptr, len);
281e2e7d0   Jeff Layton   cifs: remove the ...
241
  	if (strncmp(ses->serverOS, "OS/2", 4) == 0)
f96637be0   Joe Perches   [CIFS] cifs: Rena...
242
243
  		cifs_dbg(FYI, "OS/2 server
  ");
3979877e5   Steve French   [CIFS] Support fo...
244
245
246
247
248
  
  	bcc_ptr += len + 1;
  	bleft -= len + 1;
  
  	len = strnlen(bcc_ptr, bleft);
790fe579f   Steve French   [CIFS] more white...
249
  	if (len >= bleft)
7d0664596   Jeff Layton   cifs: make decode...
250
  		return;
3979877e5   Steve French   [CIFS] Support fo...
251

26f57364d   Steve French   [CIFS] formatting...
252
  	kfree(ses->serverNOS);
3979877e5   Steve French   [CIFS] Support fo...
253
254
  
  	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
790fe579f   Steve French   [CIFS] more white...
255
  	if (ses->serverNOS)
3979877e5   Steve French   [CIFS] Support fo...
256
257
258
259
  		strncpy(ses->serverNOS, bcc_ptr, len);
  
  	bcc_ptr += len + 1;
  	bleft -= len + 1;
790fe579f   Steve French   [CIFS] more white...
260
261
  	len = strnlen(bcc_ptr, bleft);
  	if (len > bleft)
7d0664596   Jeff Layton   cifs: make decode...
262
  		return;
3979877e5   Steve French   [CIFS] Support fo...
263

9ac00b7d9   Steve French   [CIFS] Do not sen...
264
265
266
267
268
  	/* 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 */
f96637be0   Joe Perches   [CIFS] cifs: Rena...
269
270
  	cifs_dbg(FYI, "ascii: bytes left %d
  ", bleft);
3979877e5   Steve French   [CIFS] Support fo...
271
  }
5478f9ba9   Pavel Shilovsky   CIFS: Add session...
272
  int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
96daf2b09   Steve French   [CIFS] Rename thr...
273
  				    struct cifs_ses *ses)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
274
  {
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
275
276
  	unsigned int tioffset; /* challenge message target info area */
  	unsigned int tilen; /* challenge message target info area length  */
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
277
278
279
  	CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
  
  	if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
280
281
  		cifs_dbg(VFS, "challenge blob len %d too small
  ", blob_len);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
282
283
284
285
  		return -EINVAL;
  	}
  
  	if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
286
287
288
  		cifs_dbg(VFS, "blob signature incorrect %s
  ",
  			 pblob->Signature);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
289
290
291
  		return -EINVAL;
  	}
  	if (pblob->MessageType != NtLmChallenge) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
292
293
294
  		cifs_dbg(VFS, "Incorrect message type %d
  ",
  			 pblob->MessageType);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
295
296
  		return -EINVAL;
  	}
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
297
  	memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
298
299
300
301
  	/* 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...
302
  	ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
5443d130a   Steve French   various endian fi...
303
304
  	tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
  	tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
4991a5faa   Dan Carpenter   cifs: check offse...
305
  	if (tioffset > blob_len || tioffset + tilen > blob_len) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
306
307
  		cifs_dbg(VFS, "tioffset + tilen too high %u + %u",
  			tioffset, tilen);
4991a5faa   Dan Carpenter   cifs: check offse...
308
309
  		return -EINVAL;
  	}
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
310
  	if (tilen) {
f7f7c1850   Silviu-Mihai Popescu   fs: cifs: use kme...
311
312
  		ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
  						 GFP_KERNEL);
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
313
  		if (!ses->auth_key.response) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
314
  			cifs_dbg(VFS, "Challenge target info alloc failure");
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
315
316
  			return -ENOMEM;
  		}
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
317
  		ses->auth_key.len = tilen;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
318
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
319
320
  	return 0;
  }
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
321
322
323
324
  /* 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 */
5478f9ba9   Pavel Shilovsky   CIFS: Add session...
325
  void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
96daf2b09   Steve French   [CIFS] Rename thr...
326
  					 struct cifs_ses *ses)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
327
328
329
  {
  	NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
  	__u32 flags;
df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
330
  	memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
331
332
333
334
335
336
  	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...
337
  		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
38d77c50b   Jeff Layton   cifs: track the e...
338
  	if (ses->server->sign) {
745e507a9   Steve French   Revert "missing c...
339
  		flags |= NTLMSSP_NEGOTIATE_SIGN;
5c234aa5e   Shirish Pargaonkar   cifs: Add a varia...
340
341
  		if (!ses->server->session_estab ||
  				ses->ntlmssp->sesskey_per_smbsess)
62411ab2f   Shirish Pargaonkar   cifs: Fix signing...
342
  			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
343
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
344

df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
345
  	sec_blob->NegotiateFlags = cpu_to_le32(flags);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
  
  	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 */
5478f9ba9   Pavel Shilovsky   CIFS: Add session...
360
  int build_ntlmssp_auth_blob(unsigned char *pbuffer,
89f150f40   Shirish Pargaonkar   Clean up two decl...
361
  					u16 *buflen,
96daf2b09   Steve French   [CIFS] Rename thr...
362
  				   struct cifs_ses *ses,
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
363
  				   const struct nls_table *nls_cp)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
364
  {
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
365
  	int rc;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
366
367
368
  	AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
  	__u32 flags;
  	unsigned char *tmp;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
369
370
371
372
373
374
375
  
  	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...
376
  		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
38d77c50b   Jeff Layton   cifs: track the e...
377
  	if (ses->server->sign) {
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
378
  		flags |= NTLMSSP_NEGOTIATE_SIGN;
5c234aa5e   Shirish Pargaonkar   cifs: Add a varia...
379
380
  		if (!ses->server->session_estab ||
  				ses->ntlmssp->sesskey_per_smbsess)
62411ab2f   Shirish Pargaonkar   cifs: Fix signing...
381
382
  			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
383
384
  
  	tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
df8fbc241   Shirish Pargaonkar   cifs: Support NTL...
385
  	sec_blob->NegotiateFlags = cpu_to_le32(flags);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
386
387
388
389
390
  
  	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...
391
  	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
392
  	rc = setup_ntlmv2_rsp(ses, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
393
  	if (rc) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
394
395
  		cifs_dbg(VFS, "Error %d during NTLMSSP authentication
  ", rc);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
396
397
  		goto setup_ntlmv2_ret;
  	}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
398
399
400
  	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...
401

21e733930   Shirish Pargaonkar   NTLM auth and sig...
402
403
  	sec_blob->NtChallengeResponse.Length =
  			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
404
  	sec_blob->NtChallengeResponse.MaximumLength =
21e733930   Shirish Pargaonkar   NTLM auth and sig...
405
  			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
406
407
408
409
410
411
412
413
  
  	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;
acbbb76a2   Steve French   CIFS: Rename *UCS...
414
  		len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
8c3a2b4c4   Scott Lovenberg   cifs: Move string...
415
  				      CIFS_MAX_USERNAME_LEN, nls_cp);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
416
  		len *= 2; /* unicode is 2 bytes each */
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
417
418
419
420
421
  		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 ...
422
  	if (ses->user_name == NULL) {
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
423
424
425
426
427
428
  		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
  		sec_blob->UserName.Length = 0;
  		sec_blob->UserName.MaximumLength = 0;
  		tmp += 2;
  	} else {
  		int len;
acbbb76a2   Steve French   CIFS: Rename *UCS...
429
  		len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
8c3a2b4c4   Scott Lovenberg   cifs: Move string...
430
  				      CIFS_MAX_USERNAME_LEN, nls_cp);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
431
  		len *= 2; /* unicode is 2 bytes each */
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
432
433
434
435
436
437
438
439
440
441
  		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...
442
443
444
  	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...
445
  		memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
446
447
448
449
450
451
452
453
454
455
  		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...
456
457
  
  setup_ntlmv2_ret:
89f150f40   Shirish Pargaonkar   Clean up two decl...
458
459
  	*buflen = tmp - pbuffer;
  	return rc;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
460
  }
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
461

3f618223d   Jeff Layton   move sectype to t...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
  enum securityEnum
  select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
  {
  	switch (server->negflavor) {
  	case CIFS_NEGFLAVOR_EXTENDED:
  		switch (requested) {
  		case Kerberos:
  		case RawNTLMSSP:
  			return requested;
  		case Unspecified:
  			if (server->sec_ntlmssp &&
  			    (global_secflags & CIFSSEC_MAY_NTLMSSP))
  				return RawNTLMSSP;
  			if ((server->sec_kerberos || server->sec_mskerberos) &&
  			    (global_secflags & CIFSSEC_MAY_KRB5))
  				return Kerberos;
  			/* Fallthrough */
  		default:
  			return Unspecified;
  		}
  	case CIFS_NEGFLAVOR_UNENCAP:
  		switch (requested) {
  		case NTLM:
  		case NTLMv2:
  			return requested;
  		case Unspecified:
  			if (global_secflags & CIFSSEC_MAY_NTLMV2)
  				return NTLMv2;
  			if (global_secflags & CIFSSEC_MAY_NTLM)
  				return NTLM;
3f618223d   Jeff Layton   move sectype to t...
492
  		default:
dde2356c8   Sachin Prabhu   cifs: Allow LANMA...
493
494
  			/* Fallthrough to attempt LANMAN authentication next */
  			break;
3f618223d   Jeff Layton   move sectype to t...
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  		}
  	case CIFS_NEGFLAVOR_LANMAN:
  		switch (requested) {
  		case LANMAN:
  			return requested;
  		case Unspecified:
  			if (global_secflags & CIFSSEC_MAY_LANMAN)
  				return LANMAN;
  			/* Fallthrough */
  		default:
  			return Unspecified;
  		}
  	default:
  		return Unspecified;
  	}
  }
790fe579f   Steve French   [CIFS] more white...
511
  int
58c45c58a   Pavel Shilovsky   CIFS: Move protoc...
512
  CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
ebe6aa5ac   Jeff Layton   cifs: eliminate "...
513
  	       const struct nls_table *nls_cp)
3979877e5   Steve French   [CIFS] Support fo...
514
515
516
  {
  	int rc = 0;
  	int wct;
3979877e5   Steve French   [CIFS] Support fo...
517
518
  	struct smb_hdr *smb_buf;
  	char *bcc_ptr;
750d1151a   Steve French   [CIFS] Fix alloca...
519
  	char *str_area;
3979877e5   Steve French   [CIFS] Support fo...
520
521
  	SESSION_SETUP_ANDX *pSMB;
  	__u32 capabilities;
690c522fa   Jeff Layton   cifs: use get/put...
522
  	__u16 count;
2442421b1   Steve French   [CIFS] Have CIFS_...
523
524
  	int resp_buf_type;
  	struct kvec iov[3];
3979877e5   Steve French   [CIFS] Support fo...
525
  	enum securityEnum type;
690c522fa   Jeff Layton   cifs: use get/put...
526
  	__u16 action, bytes_remaining;
2442421b1   Steve French   [CIFS] Have CIFS_...
527
  	struct key *spnego_key = NULL;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
528
  	__le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
89f150f40   Shirish Pargaonkar   Clean up two decl...
529
  	u16 blob_len;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
530
  	char *ntlmsspblob = NULL;
254e55ed0   Steve French   CIFS] Support for...
531

3534b8508   Jeff Layton   cifs: throw a war...
532
533
  	if (ses == NULL) {
  		WARN(1, "%s: ses == NULL!", __func__);
3979877e5   Steve French   [CIFS] Support fo...
534
  		return -EINVAL;
3534b8508   Jeff Layton   cifs: throw a war...
535
  	}
3979877e5   Steve French   [CIFS] Support fo...
536

3f618223d   Jeff Layton   move sectype to t...
537
  	type = select_sectype(ses->server, ses->sectype);
f96637be0   Joe Perches   [CIFS] cifs: Rena...
538
539
  	cifs_dbg(FYI, "sess setup type %d
  ", type);
3f618223d   Jeff Layton   move sectype to t...
540
  	if (type == Unspecified) {
d4e63bd6e   Shirish Pargaonkar   cifs: Process pos...
541
542
  		cifs_dbg(VFS,
  			"Unable to select appropriate authentication method!");
3f618223d   Jeff Layton   move sectype to t...
543
544
  		return -EINVAL;
  	}
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
545
546
547
548
549
550
551
  	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;
5c234aa5e   Shirish Pargaonkar   cifs: Add a varia...
552
  		ses->ntlmssp->sesskey_per_smbsess = false;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
553
  	}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
554
555
556
  ssetup_ntlmssp_authenticate:
  	if (phase == NtLmChallenge)
  		phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
790fe579f   Steve French   [CIFS] more white...
557
  	if (type == LANMAN) {
3979877e5   Steve French   [CIFS] Support fo...
558
559
560
561
562
563
564
565
566
  #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...
567
  	} else if ((type == NTLM) || (type == NTLMv2)) {
9312f6754   Steve French   [CIFS] Fix mask s...
568
  		/* For NTLMv2 failures eventually may need to retry NTLM */
3979877e5   Steve French   [CIFS] Support fo...
569
  		wct = 13; /* old style NTLM sessionsetup */
790fe579f   Steve French   [CIFS] more white...
570
  	} else /* same size: negotiate or auth, NTLMSSP or extended security */
3979877e5   Steve French   [CIFS] Support fo...
571
572
573
574
  		wct = 12;
  
  	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
  			    (void **)&smb_buf);
790fe579f   Steve French   [CIFS] more white...
575
  	if (rc)
3979877e5   Steve French   [CIFS] Support fo...
576
577
578
579
580
  		return rc;
  
  	pSMB = (SESSION_SETUP_ANDX *)smb_buf;
  
  	capabilities = cifs_ssetup_hdr(ses, pSMB);
750d1151a   Steve French   [CIFS] Fix alloca...
581

2442421b1   Steve French   [CIFS] Have CIFS_...
582
583
584
585
586
587
  	/* 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...
588
  	iov[0].iov_base = (char *)pSMB;
be8e3b004   Steve French   consistently use ...
589
  	iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
750d1151a   Steve French   [CIFS] Fix alloca...
590

2442421b1   Steve French   [CIFS] Have CIFS_...
591
592
593
  	/* 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...
594
595
  	/* 2000 big enough to fit max user, domain, NOS name etc. */
  	str_area = kmalloc(2000, GFP_KERNEL);
5e6e62327   Cyrill Gorcunov   [CIFS] Check retu...
596
  	if (str_area == NULL) {
2442421b1   Steve French   [CIFS] Have CIFS_...
597
598
  		rc = -ENOMEM;
  		goto ssetup_exit;
5e6e62327   Cyrill Gorcunov   [CIFS] Check retu...
599
  	}
750d1151a   Steve French   [CIFS] Fix alloca...
600
  	bcc_ptr = str_area;
3979877e5   Steve French   [CIFS] Support fo...
601

2442421b1   Steve French   [CIFS] Have CIFS_...
602
603
  	iov[1].iov_base = NULL;
  	iov[1].iov_len = 0;
790fe579f   Steve French   [CIFS] more white...
604
  	if (type == LANMAN) {
3979877e5   Steve French   [CIFS] Support fo...
605
  #ifdef CONFIG_CIFS_WEAK_PW_HASH
5e640927a   Shirish Pargaonkar   cifs: Fix regress...
606
  		char lnm_session_key[CIFS_AUTH_RESP_SIZE];
3979877e5   Steve French   [CIFS] Support fo...
607

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

d3ba50b17   Shirish Pargaonkar   NTLM auth and sig...
612
613
614
615
616
  		/* 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...
617
  		rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
96daf2b09   Steve French   [CIFS] Rename thr...
618
  				 ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
4e53a3fb9   Jeff Layton   cifs: have calc_l...
619
  					true : false, lnm_session_key);
5e640927a   Shirish Pargaonkar   cifs: Fix regress...
620
621
  		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
  		bcc_ptr += CIFS_AUTH_RESP_SIZE;
3979877e5   Steve French   [CIFS] Support fo...
622
623
624
625
626
  
  		/* 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? */
f96637be0   Joe Perches   [CIFS] cifs: Rena...
627
628
  		cifs_dbg(FYI, "Negotiating LANMAN setting up strings
  ");
3979877e5   Steve French   [CIFS] Support fo...
629
630
  		/* Unicode not allowed for LANMAN dialects */
  		ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
790fe579f   Steve French   [CIFS] more white...
631
  #endif
3979877e5   Steve French   [CIFS] Support fo...
632
  	} else if (type == NTLM) {
3979877e5   Steve French   [CIFS] Support fo...
633
634
  		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
  		pSMB->req_no_secext.CaseInsensitivePasswordLength =
21e733930   Shirish Pargaonkar   NTLM auth and sig...
635
  			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
3979877e5   Steve French   [CIFS] Support fo...
636
  		pSMB->req_no_secext.CaseSensitivePasswordLength =
21e733930   Shirish Pargaonkar   NTLM auth and sig...
637
638
639
  			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
  
  		/* calculate ntlm response and session key */
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
640
  		rc = setup_ntlm_response(ses, nls_cp);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
641
  		if (rc) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
642
643
644
  			cifs_dbg(VFS, "Error %d during NTLM authentication
  ",
  				 rc);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
645
646
  			goto ssetup_exit;
  		}
50c2f7538   Steve French   [CIFS] whitespace...
647

21e733930   Shirish Pargaonkar   NTLM auth and sig...
648
649
650
651
652
653
654
  		/* 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...
655

790fe579f   Steve French   [CIFS] more white...
656
  		if (ses->capabilities & CAP_UNICODE) {
0223cf0b1   Steve French   [CIFS] Fix alignm...
657
658
659
  			/* unicode strings must be word aligned */
  			if (iov[0].iov_len % 2) {
  				*bcc_ptr = 0;
790fe579f   Steve French   [CIFS] more white...
660
661
  				bcc_ptr++;
  			}
7c7b25bc8   Steve French   [CIFS] Support fo...
662
  			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b1   Steve French   [CIFS] Fix alignm...
663
  		} else
7c7b25bc8   Steve French   [CIFS] Support fo...
664
665
  			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
  	} else if (type == NTLMv2) {
7c7b25bc8   Steve French   [CIFS] Support fo...
666
667
668
669
  		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...
670

21e733930   Shirish Pargaonkar   NTLM auth and sig...
671
672
  		/* calculate nlmv2 response and session key */
  		rc = setup_ntlmv2_rsp(ses, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
673
  		if (rc) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
674
675
676
  			cifs_dbg(VFS, "Error %d during NTLMv2 authentication
  ",
  				 rc);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
677
678
  			goto ssetup_exit;
  		}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
679
680
681
  		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...
682
683
684
685
  		/* 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...
686
  			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
c9928f704   Shirish Pargaonkar   ntlm authenticati...
687

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

2442421b1   Steve French   [CIFS] Have CIFS_...
700
701
702
703
704
705
706
707
  		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...
708
709
710
  		/* 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) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
711
712
  			cifs_dbg(VFS, "incorrect version of cifs.upcall "
  				   "expected %d but got %d)",
b6b38f704   Joe Perches   [CIFS] Neaten cER...
713
  				   CIFS_SPNEGO_UPCALL_VERSION, msg->version);
6ce5eecb9   Steve French   [CIFS] check vers...
714
715
716
  			rc = -EKEYREJECTED;
  			goto ssetup_exit;
  		}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
717

f7f7c1850   Silviu-Mihai Popescu   fs: cifs: use kme...
718
719
  		ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
  						 GFP_KERNEL);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
720
  		if (!ses->auth_key.response) {
d4e63bd6e   Shirish Pargaonkar   cifs: Process pos...
721
722
723
  			cifs_dbg(VFS,
  				"Kerberos can't allocate (%u bytes) memory",
  				msg->sesskey_len);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
724
  			rc = -ENOMEM;
2442421b1   Steve French   [CIFS] Have CIFS_...
725
726
  			goto ssetup_exit;
  		}
5d0d28824   Shirish Pargaonkar   NTLM authenticati...
727
  		ses->auth_key.len = msg->sesskey_len;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
728

3979877e5   Steve French   [CIFS] Support fo...
729
730
731
  		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
  		capabilities |= CAP_EXTENDED_SECURITY;
  		pSMB->req.Capabilities = cpu_to_le32(capabilities);
2442421b1   Steve French   [CIFS] Have CIFS_...
732
733
734
735
736
737
  		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...
738
  			if ((iov[0].iov_len + iov[1].iov_len) % 2) {
2442421b1   Steve French   [CIFS] Have CIFS_...
739
740
741
742
743
744
745
746
747
  				*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 */
f96637be0   Joe Perches   [CIFS] cifs: Rena...
748
749
  		cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!
  ");
2442421b1   Steve French   [CIFS] Have CIFS_...
750
751
752
  		rc = -ENOSYS;
  		goto ssetup_exit;
  #endif /* CONFIG_CIFS_UPCALL */
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
753
754
  	} else if (type == RawNTLMSSP) {
  		if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
755
756
  			cifs_dbg(VFS, "NTLMSSP requires Unicode support
  ");
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
757
758
759
  			rc = -ENOSYS;
  			goto ssetup_exit;
  		}
f96637be0   Joe Perches   [CIFS] cifs: Rena...
760
761
  		cifs_dbg(FYI, "ntlmssp session setup phase %d
  ", phase);
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
  		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) {
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
784
  				rc = -ENOMEM;
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
785
786
  				goto ssetup_exit;
  			}
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
787
788
789
  			rc = build_ntlmssp_auth_blob(ntlmsspblob,
  						&blob_len, ses, nls_cp);
  			if (rc)
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
790
  				goto ssetup_exit;
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
791
792
793
794
795
796
797
798
799
800
801
  			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:
f96637be0   Joe Perches   [CIFS] cifs: Rena...
802
803
  			cifs_dbg(VFS, "invalid phase %d
  ", phase);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
804
805
806
  			rc = -ENOSYS;
  			goto ssetup_exit;
  		}
b4d6fcf13   Jeff Layton   cifs: move "ntlms...
807
808
809
810
811
812
813
  		/* 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 {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
814
815
  		cifs_dbg(VFS, "secType %d not supported!
  ", type);
2442421b1   Steve French   [CIFS] Have CIFS_...
816
817
  		rc = -ENOSYS;
  		goto ssetup_exit;
3979877e5   Steve French   [CIFS] Support fo...
818
  	}
2442421b1   Steve French   [CIFS] Have CIFS_...
819
820
821
822
  	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 ...
823
824
  	smb_buf->smb_buf_length =
  		cpu_to_be32(be32_to_cpu(smb_buf->smb_buf_length) + count);
3979877e5   Steve French   [CIFS] Support fo...
825

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

2442421b1   Steve French   [CIFS] Have CIFS_...
828
  	rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
7749981ec   Jeff Layton   cifs: remove code...
829
  			  CIFS_LOG_ERROR);
3979877e5   Steve French   [CIFS] Support fo...
830
  	/* SMB request buf freed in SendReceive2 */
3979877e5   Steve French   [CIFS] Support fo...
831
832
  	pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
  	smb_buf = (struct smb_hdr *)iov[0].iov_base;
f065fd099   Pavel Shilovsky   CIFS: Fix possibl...
833
834
  	if ((type == RawNTLMSSP) && (resp_buf_type != CIFS_NO_BUFFER) &&
  	    (smb_buf->Status.CifsError ==
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
835
836
  			cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
  		if (phase != NtLmNegotiate) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
837
838
  			cifs_dbg(VFS, "Unexpected more processing error
  ");
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
839
840
841
842
843
844
845
846
  			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...
847
  	if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
3979877e5   Steve French   [CIFS] Support fo...
848
  		rc = -EIO;
f96637be0   Joe Perches   [CIFS] cifs: Rena...
849
850
  		cifs_dbg(VFS, "bad word count %d
  ", smb_buf->WordCount);
3979877e5   Steve French   [CIFS] Support fo...
851
852
853
854
  		goto ssetup_exit;
  	}
  	action = le16_to_cpu(pSMB->resp.Action);
  	if (action & GUEST_LOGIN)
f96637be0   Joe Perches   [CIFS] cifs: Rena...
855
856
  		cifs_dbg(FYI, "Guest login
  "); /* BB mark SesInfo struct? */
3979877e5   Steve French   [CIFS] Support fo...
857
  	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
f96637be0   Joe Perches   [CIFS] cifs: Rena...
858
859
  	cifs_dbg(FYI, "UID = %llu
  ", ses->Suid);
3979877e5   Steve French   [CIFS] Support fo...
860
861
  	/* response can have either 3 or 4 word count - Samba sends 3 */
  	/* and lanman response is 3 */
690c522fa   Jeff Layton   cifs: use get/put...
862
  	bytes_remaining = get_bcc(smb_buf);
3979877e5   Steve French   [CIFS] Support fo...
863
  	bcc_ptr = pByteArea(smb_buf);
790fe579f   Steve French   [CIFS] more white...
864
  	if (smb_buf->WordCount == 4) {
3979877e5   Steve French   [CIFS] Support fo...
865
  		blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
790fe579f   Steve French   [CIFS] more white...
866
  		if (blob_len > bytes_remaining) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
867
868
869
  			cifs_dbg(VFS, "bad security blob length %d
  ",
  				 blob_len);
3979877e5   Steve French   [CIFS] Support fo...
870
871
872
  			rc = -EINVAL;
  			goto ssetup_exit;
  		}
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
873
874
875
876
877
878
879
  		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...
880
  		bytes_remaining -= blob_len;
790fe579f   Steve French   [CIFS] more white...
881
  	}
3979877e5   Steve French   [CIFS] Support fo...
882
883
  
  	/* BB check if Unicode and decode strings */
fcda7f457   Jeff Layton   cifs: check for b...
884
885
886
  	if (bytes_remaining == 0) {
  		/* no string area to decode, do nothing */
  	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
27b87fe52   Jeff Layton   cifs: fix unicode...
887
888
889
890
891
  		/* 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...
892
  		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
27b87fe52   Jeff Layton   cifs: fix unicode...
893
  	} else {
7d0664596   Jeff Layton   cifs: make decode...
894
  		decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
27b87fe52   Jeff Layton   cifs: fix unicode...
895
  	}
50c2f7538   Steve French   [CIFS] whitespace...
896

3979877e5   Steve French   [CIFS] Support fo...
897
  ssetup_exit:
dfd15c46a   Jeff Layton   cifs: explicitly ...
898
  	if (spnego_key) {
00401ff78   Jeff Layton   cifs: after upcal...
899
  		key_invalidate(spnego_key);
2442421b1   Steve French   [CIFS] Have CIFS_...
900
  		key_put(spnego_key);
dfd15c46a   Jeff Layton   cifs: explicitly ...
901
  	}
750d1151a   Steve French   [CIFS] Fix alloca...
902
  	kfree(str_area);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
903
904
  	kfree(ntlmsspblob);
  	ntlmsspblob = NULL;
790fe579f   Steve French   [CIFS] more white...
905
  	if (resp_buf_type == CIFS_SMALL_BUFFER) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
906
907
  		cifs_dbg(FYI, "ssetup freeing small buf %p
  ", iov[0].iov_base);
3979877e5   Steve French   [CIFS] Support fo...
908
  		cifs_small_buf_release(iov[0].iov_base);
790fe579f   Steve French   [CIFS] more white...
909
  	} else if (resp_buf_type == CIFS_LARGE_BUFFER)
3979877e5   Steve French   [CIFS] Support fo...
910
  		cifs_buf_release(iov[0].iov_base);
0b3cc8580   Steve French   [CIFS] NTLMSSP re...
911
912
913
  	/* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
  	if ((phase == NtLmChallenge) && (rc == 0))
  		goto ssetup_ntlmssp_authenticate;
d4e63bd6e   Shirish Pargaonkar   cifs: Process pos...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
  	if (!rc) {
  		mutex_lock(&ses->server->srv_mutex);
  		if (!ses->server->session_estab) {
  			if (ses->server->sign) {
  				ses->server->session_key.response =
  					kmemdup(ses->auth_key.response,
  					ses->auth_key.len, GFP_KERNEL);
  				if (!ses->server->session_key.response) {
  					rc = -ENOMEM;
  					mutex_unlock(&ses->server->srv_mutex);
  					goto keycp_exit;
  				}
  				ses->server->session_key.len =
  							ses->auth_key.len;
  			}
  			ses->server->sequence_number = 0x2;
  			ses->server->session_estab = true;
  		}
  		mutex_unlock(&ses->server->srv_mutex);
  
  		cifs_dbg(FYI, "CIFS session established successfully
  ");
  		spin_lock(&GlobalMid_Lock);
  		ses->status = CifsGood;
  		ses->need_reconnect = false;
  		spin_unlock(&GlobalMid_Lock);
  	}
  
  keycp_exit:
  	kfree(ses->auth_key.response);
  	ses->auth_key.response = NULL;
  	kfree(ses->ntlmssp);
3979877e5   Steve French   [CIFS] Support fo...
946
947
  	return rc;
  }