1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3 *
4 * SMB/CIFS session setup handling routines
5 *
6 * Copyright (c) International Business Machines Corp., 2006, 2009
7 * Author(s): Steve French (sfrench@us.ibm.com)
8 *
9 */
10
11 #include "cifsproto.h"
12 #include "smb1proto.h"
13 #include "ntlmssp.h"
14 #include "nterr.h"
15 #include "cifs_spnego.h"
16 #include "cifs_unicode.h"
17 #include "cifs_debug.h"
18
19 struct sess_data {
20 unsigned int xid;
21 struct cifs_ses *ses;
22 struct TCP_Server_Info *server;
23 struct nls_table *nls_cp;
24 void (*func)(struct sess_data *);
25 int result;
26 unsigned int in_len;
27
28 /* we will send the SMB in three pieces:
29 * a fixed length beginning part, an optional
30 * SPNEGO blob (which can be zero length), and a
31 * last part which will include the strings
32 * and rest of bcc area. This allows us to avoid
33 * a large buffer 17K allocation
34 */
35 int buf0_type;
36 struct kvec iov[3];
37 };
38
cifs_ssetup_hdr(struct cifs_ses * ses,struct TCP_Server_Info * server,SESSION_SETUP_ANDX * pSMB)39 static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,
40 struct TCP_Server_Info *server,
41 SESSION_SETUP_ANDX *pSMB)
42 {
43 __u32 capabilities = 0;
44
45 /* init fields common to all four types of SessSetup */
46 /* Note that offsets for first seven fields in req struct are same */
47 /* in CIFS Specs so does not matter which of 3 forms of struct */
48 /* that we use in next few lines */
49 /* Note that header is initialized to zero in header_assemble */
50 pSMB->req.AndXCommand = 0xFF;
51 pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
52 CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
53 USHRT_MAX));
54 pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq);
55 pSMB->req.VcNumber = cpu_to_le16(1);
56 pSMB->req.SessionKey = server->session_key_id;
57
58 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
59
60 /* BB verify whether signing required on neg or just auth frame (and NTLM case) */
61
62 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
63 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
64
65 if (server->sign)
66 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
67
68 if (ses->capabilities & CAP_UNICODE) {
69 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
70 capabilities |= CAP_UNICODE;
71 }
72 if (ses->capabilities & CAP_STATUS32) {
73 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
74 capabilities |= CAP_STATUS32;
75 }
76 if (ses->capabilities & CAP_DFS) {
77 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
78 capabilities |= CAP_DFS;
79 }
80 if (ses->capabilities & CAP_UNIX)
81 capabilities |= CAP_UNIX;
82
83 return capabilities;
84 }
85
86 static void
unicode_oslm_strings(char ** pbcc_area,const struct nls_table * nls_cp)87 unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
88 {
89 char *bcc_ptr = *pbcc_area;
90 int bytes_ret = 0;
91
92 /* Copy OS version */
93 bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
94 nls_cp);
95 bcc_ptr += 2 * bytes_ret;
96 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
97 32, nls_cp);
98 bcc_ptr += 2 * bytes_ret;
99 bcc_ptr += 2; /* trailing null */
100
101 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
102 32, nls_cp);
103 bcc_ptr += 2 * bytes_ret;
104 bcc_ptr += 2; /* trailing null */
105
106 *pbcc_area = bcc_ptr;
107 }
108
109 static void
ascii_oslm_strings(char ** pbcc_area,const struct nls_table * nls_cp)110 ascii_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
111 {
112 char *bcc_ptr = *pbcc_area;
113
114 strcpy(bcc_ptr, "Linux version ");
115 bcc_ptr += strlen("Linux version ");
116 strcpy(bcc_ptr, init_utsname()->release);
117 bcc_ptr += strlen(init_utsname()->release) + 1;
118
119 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
120 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
121
122 *pbcc_area = bcc_ptr;
123 }
124
unicode_domain_string(char ** pbcc_area,struct cifs_ses * ses,const struct nls_table * nls_cp)125 static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
126 const struct nls_table *nls_cp)
127 {
128 char *bcc_ptr = *pbcc_area;
129 int bytes_ret = 0;
130
131 /* copy domain */
132 if (ses->domainName == NULL) {
133 /*
134 * Sending null domain better than using a bogus domain name (as
135 * we did briefly in 2.6.18) since server will use its default
136 */
137 *bcc_ptr = 0;
138 *(bcc_ptr+1) = 0;
139 bytes_ret = 0;
140 } else
141 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
142 CIFS_MAX_DOMAINNAME_LEN, nls_cp);
143 bcc_ptr += 2 * bytes_ret;
144 bcc_ptr += 2; /* account for null terminator */
145
146 *pbcc_area = bcc_ptr;
147 }
148
ascii_domain_string(char ** pbcc_area,struct cifs_ses * ses,const struct nls_table * nls_cp)149 static void ascii_domain_string(char **pbcc_area, struct cifs_ses *ses,
150 const struct nls_table *nls_cp)
151 {
152 char *bcc_ptr = *pbcc_area;
153 int len;
154
155 /* copy domain */
156 if (ses->domainName != NULL) {
157 len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
158 if (WARN_ON_ONCE(len < 0))
159 len = CIFS_MAX_DOMAINNAME_LEN - 1;
160 bcc_ptr += len;
161 } /* else we send a null domain name so server will default to its own domain */
162 *bcc_ptr = 0;
163 bcc_ptr++;
164
165 *pbcc_area = bcc_ptr;
166 }
167
unicode_ssetup_strings(char ** pbcc_area,struct cifs_ses * ses,const struct nls_table * nls_cp)168 static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
169 const struct nls_table *nls_cp)
170 {
171 char *bcc_ptr = *pbcc_area;
172 int bytes_ret = 0;
173
174 /* BB FIXME add check that strings less than 335 or will need to send as arrays */
175
176 /* copy user */
177 if (ses->user_name == NULL) {
178 /* null user mount */
179 *bcc_ptr = 0;
180 *(bcc_ptr+1) = 0;
181 } else {
182 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
183 CIFS_MAX_USERNAME_LEN, nls_cp);
184 }
185 bcc_ptr += 2 * bytes_ret;
186 bcc_ptr += 2; /* account for null termination */
187
188 unicode_domain_string(&bcc_ptr, ses, nls_cp);
189 unicode_oslm_strings(&bcc_ptr, nls_cp);
190
191 *pbcc_area = bcc_ptr;
192 }
193
ascii_ssetup_strings(char ** pbcc_area,struct cifs_ses * ses,const struct nls_table * nls_cp)194 static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
195 const struct nls_table *nls_cp)
196 {
197 char *bcc_ptr = *pbcc_area;
198 int len;
199
200 /* copy user */
201 /* BB what about null user mounts - check that we do this BB */
202 /* copy user */
203 if (ses->user_name != NULL) {
204 len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
205 if (WARN_ON_ONCE(len < 0))
206 len = CIFS_MAX_USERNAME_LEN - 1;
207 bcc_ptr += len;
208 }
209 /* else null user mount */
210 *bcc_ptr = 0;
211 bcc_ptr++; /* account for null termination */
212
213 /* BB check for overflow here */
214
215 ascii_domain_string(&bcc_ptr, ses, nls_cp);
216 ascii_oslm_strings(&bcc_ptr, nls_cp);
217
218 *pbcc_area = bcc_ptr;
219 }
220
221 static void
decode_unicode_ssetup(char ** pbcc_area,int bleft,struct cifs_ses * ses,const struct nls_table * nls_cp)222 decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
223 const struct nls_table *nls_cp)
224 {
225 int len;
226 char *data = *pbcc_area;
227
228 cifs_dbg(FYI, "bleft %d\n", bleft);
229
230 kfree(ses->serverOS);
231 ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
232 cifs_dbg(FYI, "serverOS=%s\n", ses->serverOS);
233 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
234 data += len;
235 bleft -= len;
236 if (bleft <= 0)
237 return;
238
239 kfree(ses->serverNOS);
240 ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
241 cifs_dbg(FYI, "serverNOS=%s\n", ses->serverNOS);
242 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
243 data += len;
244 bleft -= len;
245 if (bleft <= 0)
246 return;
247
248 kfree(ses->serverDomain);
249 ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
250 cifs_dbg(FYI, "serverDomain=%s\n", ses->serverDomain);
251
252 return;
253 }
254
decode_ascii_ssetup(char ** pbcc_area,__u16 bleft,struct cifs_ses * ses,const struct nls_table * nls_cp)255 static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
256 struct cifs_ses *ses,
257 const struct nls_table *nls_cp)
258 {
259 int len;
260 char *bcc_ptr = *pbcc_area;
261
262 cifs_dbg(FYI, "decode sessetup ascii. bleft %d\n", bleft);
263
264 len = strnlen(bcc_ptr, bleft);
265 if (len >= bleft)
266 return;
267
268 kfree(ses->serverOS);
269
270 ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
271 if (ses->serverOS) {
272 memcpy(ses->serverOS, bcc_ptr, len);
273 ses->serverOS[len] = 0;
274 if (strncmp(ses->serverOS, "OS/2", 4) == 0)
275 cifs_dbg(FYI, "OS/2 server\n");
276 }
277
278 bcc_ptr += len + 1;
279 bleft -= len + 1;
280
281 len = strnlen(bcc_ptr, bleft);
282 if (len >= bleft)
283 return;
284
285 kfree(ses->serverNOS);
286
287 ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
288 if (ses->serverNOS) {
289 memcpy(ses->serverNOS, bcc_ptr, len);
290 ses->serverNOS[len] = 0;
291 }
292
293 bcc_ptr += len + 1;
294 bleft -= len + 1;
295
296 len = strnlen(bcc_ptr, bleft);
297 if (len > bleft)
298 return;
299
300 /*
301 * No domain field in LANMAN case. Domain is
302 * returned by old servers in the SMB negprot response
303 *
304 * BB For newer servers which do not support Unicode,
305 * but thus do return domain here, we could add parsing
306 * for it later, but it is not very important
307 */
308 cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
309 }
310
311 static int
sess_alloc_buffer(struct sess_data * sess_data,int wct)312 sess_alloc_buffer(struct sess_data *sess_data, int wct)
313 {
314 int rc;
315 struct cifs_ses *ses = sess_data->ses;
316 struct smb_hdr *smb_buf;
317
318 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
319 (void **)&smb_buf);
320
321 if (rc < 0)
322 return rc;
323
324 sess_data->in_len = rc;
325 sess_data->iov[0].iov_base = (char *)smb_buf;
326 sess_data->iov[0].iov_len = sess_data->in_len;
327 /*
328 * This variable will be used to clear the buffer
329 * allocated above in case of any error in the calling function.
330 */
331 sess_data->buf0_type = CIFS_SMALL_BUFFER;
332
333 /* 2000 big enough to fit max user, domain, NOS name etc. */
334 sess_data->iov[2].iov_base = kmalloc(2000, GFP_KERNEL);
335 if (!sess_data->iov[2].iov_base) {
336 rc = -ENOMEM;
337 goto out_free_smb_buf;
338 }
339
340 return 0;
341
342 out_free_smb_buf:
343 cifs_small_buf_release(smb_buf);
344 sess_data->iov[0].iov_base = NULL;
345 sess_data->iov[0].iov_len = 0;
346 sess_data->buf0_type = CIFS_NO_BUFFER;
347 return rc;
348 }
349
350 static void
sess_free_buffer(struct sess_data * sess_data)351 sess_free_buffer(struct sess_data *sess_data)
352 {
353 struct kvec *iov = sess_data->iov;
354
355 /*
356 * Zero the session data before freeing, as it might contain sensitive info (keys, etc).
357 * Note that iov[1] is already freed by caller.
358 */
359 if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
360 memzero_explicit(iov[0].iov_base, iov[0].iov_len);
361
362 free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
363 sess_data->buf0_type = CIFS_NO_BUFFER;
364 kfree_sensitive(iov[2].iov_base);
365 }
366
367 static int
sess_establish_session(struct sess_data * sess_data)368 sess_establish_session(struct sess_data *sess_data)
369 {
370 struct cifs_ses *ses = sess_data->ses;
371 struct TCP_Server_Info *server = sess_data->server;
372
373 cifs_server_lock(server);
374 if (!server->session_estab) {
375 if (server->sign) {
376 server->session_key.response =
377 kmemdup(ses->auth_key.response,
378 ses->auth_key.len, GFP_KERNEL);
379 if (!server->session_key.response) {
380 cifs_server_unlock(server);
381 return -ENOMEM;
382 }
383 server->session_key.len =
384 ses->auth_key.len;
385 }
386 server->sequence_number = 0x2;
387 server->session_estab = true;
388 }
389 cifs_server_unlock(server);
390
391 cifs_dbg(FYI, "CIFS session established successfully\n");
392 return 0;
393 }
394
395 static int
sess_sendreceive(struct sess_data * sess_data)396 sess_sendreceive(struct sess_data *sess_data)
397 {
398 int rc;
399 struct smb_hdr *smb_buf = (struct smb_hdr *) sess_data->iov[0].iov_base;
400 __u16 count;
401 struct kvec rsp_iov = { NULL, 0 };
402
403 count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
404 sess_data->in_len += count;
405 put_bcc(count, smb_buf);
406
407 rc = SendReceive2(sess_data->xid, sess_data->ses,
408 sess_data->iov, 3 /* num_iovecs */,
409 &sess_data->buf0_type,
410 CIFS_LOG_ERROR, &rsp_iov);
411 cifs_small_buf_release(sess_data->iov[0].iov_base);
412 memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
413
414 return rc;
415 }
416
417 static void
sess_auth_ntlmv2(struct sess_data * sess_data)418 sess_auth_ntlmv2(struct sess_data *sess_data)
419 {
420 int rc = 0;
421 struct smb_hdr *smb_buf;
422 SESSION_SETUP_ANDX *pSMB;
423 char *bcc_ptr;
424 struct cifs_ses *ses = sess_data->ses;
425 struct TCP_Server_Info *server = sess_data->server;
426 __u32 capabilities;
427 __u16 bytes_remaining;
428
429 /* old style NTLM sessionsetup */
430 /* wct = 13 */
431 rc = sess_alloc_buffer(sess_data, 13);
432 if (rc)
433 goto out;
434
435 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
436 bcc_ptr = sess_data->iov[2].iov_base;
437 capabilities = cifs_ssetup_hdr(ses, server, pSMB);
438
439 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
440
441 /* LM2 password would be here if we supported it */
442 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
443
444 if (ses->user_name != NULL) {
445 /* calculate nlmv2 response and session key */
446 rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
447 if (rc) {
448 cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
449 goto out;
450 }
451
452 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
453 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
454 bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
455
456 /* set case sensitive password length after tilen may get
457 * assigned, tilen is 0 otherwise.
458 */
459 pSMB->req_no_secext.CaseSensitivePasswordLength =
460 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
461 } else {
462 pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
463 }
464
465 if (ses->capabilities & CAP_UNICODE) {
466 if (!IS_ALIGNED(sess_data->iov[0].iov_len, 2)) {
467 *bcc_ptr = 0;
468 bcc_ptr++;
469 }
470 unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
471 } else {
472 ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
473 }
474
475
476 sess_data->iov[2].iov_len = (long) bcc_ptr -
477 (long) sess_data->iov[2].iov_base;
478
479 rc = sess_sendreceive(sess_data);
480 if (rc)
481 goto out;
482
483 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
484 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
485
486 if (smb_buf->WordCount != 3) {
487 rc = smb_EIO1(smb_eio_trace_sess_nl2_wcc, smb_buf->WordCount);
488 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
489 goto out;
490 }
491
492 if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
493 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
494
495 ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
496 cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
497
498 bytes_remaining = get_bcc(smb_buf);
499 bcc_ptr = pByteArea(smb_buf);
500
501 /* BB check if Unicode and decode strings */
502 if (bytes_remaining == 0) {
503 /* no string area to decode, do nothing */
504 } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
505 /* unicode string area must be word-aligned */
506 if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
507 ++bcc_ptr;
508 --bytes_remaining;
509 }
510 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
511 sess_data->nls_cp);
512 } else {
513 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
514 sess_data->nls_cp);
515 }
516
517 rc = sess_establish_session(sess_data);
518 out:
519 sess_data->result = rc;
520 sess_data->func = NULL;
521 sess_free_buffer(sess_data);
522 kfree_sensitive(ses->auth_key.response);
523 ses->auth_key.response = NULL;
524 }
525
526 #ifdef CONFIG_CIFS_UPCALL
527 static void
sess_auth_kerberos(struct sess_data * sess_data)528 sess_auth_kerberos(struct sess_data *sess_data)
529 {
530 int rc = 0;
531 struct smb_hdr *smb_buf;
532 SESSION_SETUP_ANDX *pSMB;
533 char *bcc_ptr;
534 struct cifs_ses *ses = sess_data->ses;
535 struct TCP_Server_Info *server = sess_data->server;
536 __u32 capabilities;
537 __u16 bytes_remaining;
538 struct key *spnego_key = NULL;
539 struct cifs_spnego_msg *msg;
540 u16 blob_len;
541
542 /* extended security */
543 /* wct = 12 */
544 rc = sess_alloc_buffer(sess_data, 12);
545 if (rc)
546 goto out;
547
548 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
549 bcc_ptr = sess_data->iov[2].iov_base;
550 capabilities = cifs_ssetup_hdr(ses, server, pSMB);
551
552 spnego_key = cifs_get_spnego_key(ses, server);
553 if (IS_ERR(spnego_key)) {
554 rc = PTR_ERR(spnego_key);
555 spnego_key = NULL;
556 goto out;
557 }
558
559 msg = spnego_key->payload.data[0];
560 /*
561 * check version field to make sure that cifs.upcall is
562 * sending us a response in an expected form
563 */
564 if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
565 cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n",
566 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
567 rc = -EKEYREJECTED;
568 goto out_put_spnego_key;
569 }
570
571 kfree_sensitive(ses->auth_key.response);
572 ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
573 GFP_KERNEL);
574 if (!ses->auth_key.response) {
575 cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
576 msg->sesskey_len);
577 rc = -ENOMEM;
578 goto out_put_spnego_key;
579 }
580 ses->auth_key.len = msg->sesskey_len;
581
582 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
583 capabilities |= CAP_EXTENDED_SECURITY;
584 pSMB->req.Capabilities = cpu_to_le32(capabilities);
585 sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
586 sess_data->iov[1].iov_len = msg->secblob_len;
587 pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
588
589 if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) {
590 /* unicode strings must be word aligned */
591 if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
592 *bcc_ptr = 0;
593 bcc_ptr++;
594 }
595 unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
596 unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
597 } else {
598 ascii_oslm_strings(&bcc_ptr, sess_data->nls_cp);
599 ascii_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
600 }
601
602 sess_data->iov[2].iov_len = (long) bcc_ptr -
603 (long) sess_data->iov[2].iov_base;
604
605 rc = sess_sendreceive(sess_data);
606 if (rc)
607 goto out_put_spnego_key;
608
609 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
610 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
611
612 if (smb_buf->WordCount != 4) {
613 rc = smb_EIO1(smb_eio_trace_sess_krb_wcc, smb_buf->WordCount);
614 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
615 goto out_put_spnego_key;
616 }
617
618 if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
619 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
620
621 ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
622 cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
623
624 bytes_remaining = get_bcc(smb_buf);
625 bcc_ptr = pByteArea(smb_buf);
626
627 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
628 if (blob_len > bytes_remaining) {
629 cifs_dbg(VFS, "bad security blob length %d\n",
630 blob_len);
631 rc = -EINVAL;
632 goto out_put_spnego_key;
633 }
634 bcc_ptr += blob_len;
635 bytes_remaining -= blob_len;
636
637 /* BB check if Unicode and decode strings */
638 if (bytes_remaining == 0) {
639 /* no string area to decode, do nothing */
640 } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
641 /* unicode string area must be word-aligned */
642 if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
643 ++bcc_ptr;
644 --bytes_remaining;
645 }
646 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
647 sess_data->nls_cp);
648 } else {
649 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
650 sess_data->nls_cp);
651 }
652
653 rc = sess_establish_session(sess_data);
654 out_put_spnego_key:
655 key_invalidate(spnego_key);
656 key_put(spnego_key);
657 out:
658 sess_data->result = rc;
659 sess_data->func = NULL;
660 sess_free_buffer(sess_data);
661 kfree_sensitive(ses->auth_key.response);
662 ses->auth_key.response = NULL;
663 }
664
665 #endif /* ! CONFIG_CIFS_UPCALL */
666
667 /*
668 * The required kvec buffers have to be allocated before calling this
669 * function.
670 */
671 static int
_sess_auth_rawntlmssp_assemble_req(struct sess_data * sess_data)672 _sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
673 {
674 SESSION_SETUP_ANDX *pSMB;
675 struct cifs_ses *ses = sess_data->ses;
676 struct TCP_Server_Info *server = sess_data->server;
677 __u32 capabilities;
678 char *bcc_ptr;
679
680 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
681
682 capabilities = cifs_ssetup_hdr(ses, server, pSMB);
683 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
684 capabilities |= CAP_EXTENDED_SECURITY;
685 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
686
687 bcc_ptr = sess_data->iov[2].iov_base;
688
689 if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) {
690 /* unicode strings must be word aligned */
691 if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
692 *bcc_ptr = 0;
693 bcc_ptr++;
694 }
695 unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
696 } else {
697 ascii_oslm_strings(&bcc_ptr, sess_data->nls_cp);
698 }
699
700 sess_data->iov[2].iov_len = (long) bcc_ptr -
701 (long) sess_data->iov[2].iov_base;
702
703 return 0;
704 }
705
706 static void
707 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
708
709 static void
sess_auth_rawntlmssp_negotiate(struct sess_data * sess_data)710 sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
711 {
712 int rc;
713 struct smb_hdr *smb_buf;
714 SESSION_SETUP_ANDX *pSMB;
715 struct cifs_ses *ses = sess_data->ses;
716 struct TCP_Server_Info *server = sess_data->server;
717 __u16 bytes_remaining;
718 char *bcc_ptr;
719 unsigned char *ntlmsspblob = NULL;
720 u16 blob_len;
721
722 cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
723
724 /*
725 * if memory allocation is successful, caller of this function
726 * frees it.
727 */
728 ses->ntlmssp = kmalloc_obj(struct ntlmssp_auth);
729 if (!ses->ntlmssp) {
730 rc = -ENOMEM;
731 goto out;
732 }
733 ses->ntlmssp->sesskey_per_smbsess = false;
734
735 /* wct = 12 */
736 rc = sess_alloc_buffer(sess_data, 12);
737 if (rc)
738 goto out;
739
740 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
741
742 /* Build security blob before we assemble the request */
743 rc = build_ntlmssp_negotiate_blob(&ntlmsspblob,
744 &blob_len, ses, server,
745 sess_data->nls_cp);
746 if (rc)
747 goto out_free_ntlmsspblob;
748
749 sess_data->iov[1].iov_len = blob_len;
750 sess_data->iov[1].iov_base = ntlmsspblob;
751 pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
752
753 rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
754 if (rc)
755 goto out_free_ntlmsspblob;
756
757 rc = sess_sendreceive(sess_data);
758
759 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
760 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
761
762 /* If true, rc here is expected and not an error */
763 if (sess_data->buf0_type != CIFS_NO_BUFFER &&
764 smb_buf->Status.CifsError ==
765 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
766 rc = 0;
767
768 if (rc)
769 goto out_free_ntlmsspblob;
770
771 cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
772
773 if (smb_buf->WordCount != 4) {
774 rc = smb_EIO1(smb_eio_trace_sess_rawnl_neg_wcc, smb_buf->WordCount);
775 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
776 goto out_free_ntlmsspblob;
777 }
778
779 ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
780 cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
781
782 bytes_remaining = get_bcc(smb_buf);
783 bcc_ptr = pByteArea(smb_buf);
784
785 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
786 if (blob_len > bytes_remaining) {
787 cifs_dbg(VFS, "bad security blob length %d\n",
788 blob_len);
789 rc = -EINVAL;
790 goto out_free_ntlmsspblob;
791 }
792
793 rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
794
795 out_free_ntlmsspblob:
796 kfree_sensitive(ntlmsspblob);
797 out:
798 sess_free_buffer(sess_data);
799
800 if (!rc) {
801 sess_data->func = sess_auth_rawntlmssp_authenticate;
802 return;
803 }
804
805 /* Else error. Cleanup */
806 kfree_sensitive(ses->auth_key.response);
807 ses->auth_key.response = NULL;
808 kfree_sensitive(ses->ntlmssp);
809 ses->ntlmssp = NULL;
810
811 sess_data->func = NULL;
812 sess_data->result = rc;
813 }
814
815 static void
sess_auth_rawntlmssp_authenticate(struct sess_data * sess_data)816 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
817 {
818 int rc;
819 struct smb_hdr *smb_buf;
820 SESSION_SETUP_ANDX *pSMB;
821 struct cifs_ses *ses = sess_data->ses;
822 struct TCP_Server_Info *server = sess_data->server;
823 __u16 bytes_remaining;
824 char *bcc_ptr;
825 unsigned char *ntlmsspblob = NULL;
826 u16 blob_len;
827
828 cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
829
830 /* wct = 12 */
831 rc = sess_alloc_buffer(sess_data, 12);
832 if (rc)
833 goto out;
834
835 /* Build security blob before we assemble the request */
836 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
837 smb_buf = (struct smb_hdr *)pSMB;
838 rc = build_ntlmssp_auth_blob(&ntlmsspblob,
839 &blob_len, ses, server,
840 sess_data->nls_cp);
841 if (rc)
842 goto out_free_ntlmsspblob;
843 sess_data->iov[1].iov_len = blob_len;
844 sess_data->iov[1].iov_base = ntlmsspblob;
845 pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
846 /*
847 * Make sure that we tell the server that we are using
848 * the uid that it just gave us back on the response
849 * (challenge)
850 */
851 smb_buf->Uid = ses->Suid;
852
853 rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
854 if (rc)
855 goto out_free_ntlmsspblob;
856
857 rc = sess_sendreceive(sess_data);
858 if (rc)
859 goto out_free_ntlmsspblob;
860
861 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
862 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
863 if (smb_buf->WordCount != 4) {
864 rc = smb_EIO1(smb_eio_trace_sess_rawnl_auth_wcc, smb_buf->WordCount);
865 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
866 goto out_free_ntlmsspblob;
867 }
868
869 if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
870 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
871
872 if (ses->Suid != smb_buf->Uid) {
873 ses->Suid = smb_buf->Uid;
874 cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
875 }
876
877 bytes_remaining = get_bcc(smb_buf);
878 bcc_ptr = pByteArea(smb_buf);
879 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
880 if (blob_len > bytes_remaining) {
881 cifs_dbg(VFS, "bad security blob length %d\n",
882 blob_len);
883 rc = -EINVAL;
884 goto out_free_ntlmsspblob;
885 }
886 bcc_ptr += blob_len;
887 bytes_remaining -= blob_len;
888
889
890 /* BB check if Unicode and decode strings */
891 if (bytes_remaining == 0) {
892 /* no string area to decode, do nothing */
893 } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
894 /* unicode string area must be word-aligned */
895 if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
896 ++bcc_ptr;
897 --bytes_remaining;
898 }
899 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
900 sess_data->nls_cp);
901 } else {
902 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
903 sess_data->nls_cp);
904 }
905
906 out_free_ntlmsspblob:
907 kfree_sensitive(ntlmsspblob);
908 out:
909 sess_free_buffer(sess_data);
910
911 if (!rc)
912 rc = sess_establish_session(sess_data);
913
914 /* Cleanup */
915 kfree_sensitive(ses->auth_key.response);
916 ses->auth_key.response = NULL;
917 kfree_sensitive(ses->ntlmssp);
918 ses->ntlmssp = NULL;
919
920 sess_data->func = NULL;
921 sess_data->result = rc;
922 }
923
select_sec(struct sess_data * sess_data)924 static int select_sec(struct sess_data *sess_data)
925 {
926 int type;
927 struct cifs_ses *ses = sess_data->ses;
928 struct TCP_Server_Info *server = sess_data->server;
929
930 type = cifs_select_sectype(server, ses->sectype);
931 cifs_dbg(FYI, "sess setup type %d\n", type);
932 if (type == Unspecified) {
933 cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
934 return -EINVAL;
935 }
936
937 switch (type) {
938 case NTLMv2:
939 sess_data->func = sess_auth_ntlmv2;
940 break;
941 case Kerberos:
942 #ifdef CONFIG_CIFS_UPCALL
943 sess_data->func = sess_auth_kerberos;
944 break;
945 #else
946 cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
947 return -ENOSYS;
948 #endif /* CONFIG_CIFS_UPCALL */
949 case RawNTLMSSP:
950 sess_data->func = sess_auth_rawntlmssp_negotiate;
951 break;
952 default:
953 cifs_dbg(VFS, "secType %d not supported!\n", type);
954 return -ENOSYS;
955 }
956
957 return 0;
958 }
959
CIFS_SessSetup(const unsigned int xid,struct cifs_ses * ses,struct TCP_Server_Info * server,const struct nls_table * nls_cp)960 int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
961 struct TCP_Server_Info *server,
962 const struct nls_table *nls_cp)
963 {
964 int rc = 0;
965 struct sess_data *sess_data;
966
967 if (ses == NULL) {
968 WARN(1, "%s: ses == NULL!", __func__);
969 return -EINVAL;
970 }
971
972 sess_data = kzalloc_obj(struct sess_data);
973 if (!sess_data)
974 return -ENOMEM;
975
976 sess_data->xid = xid;
977 sess_data->ses = ses;
978 sess_data->server = server;
979 sess_data->buf0_type = CIFS_NO_BUFFER;
980 sess_data->nls_cp = (struct nls_table *) nls_cp;
981
982 rc = select_sec(sess_data);
983 if (rc)
984 goto out;
985
986 while (sess_data->func)
987 sess_data->func(sess_data);
988
989 /* Store result before we free sess_data */
990 rc = sess_data->result;
991
992 out:
993 kfree_sensitive(sess_data);
994 return rc;
995 }
996