xref: /linux/fs/smb/client/cifssmb.c (revision 5dfa01ef37a8b944773aef8dee747cd76dec4234)
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2010
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for constructing the SMB PDUs themselves
8  *
9  */
10 
11  /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c   */
12  /* These are mostly routines that operate on a pathname, or on a tree id     */
13  /* (mounted volume), but there are eight handle based routines which must be */
14  /* treated slightly differently for reconnection purposes since we never     */
15  /* want to reuse a stale file handle and only the caller knows the file info */
16 
17 #include <linux/fs.h>
18 #include <linux/filelock.h>
19 #include <linux/kernel.h>
20 #include <linux/vfs.h>
21 #include <linux/slab.h>
22 #include <linux/posix_acl_xattr.h>
23 #include <linux/pagemap.h>
24 #include <linux/swap.h>
25 #include <linux/task_io_accounting_ops.h>
26 #include <linux/uaccess.h>
27 #include <linux/netfs.h>
28 #include <trace/events/netfs.h>
29 #include "cifsglob.h"
30 #include "cifsproto.h"
31 #include "smb1proto.h"
32 #include "../common/smbfsctl.h"
33 #include "cifsfs.h"
34 #include "cifsacl.h"
35 #include "cifs_unicode.h"
36 #include "cifs_debug.h"
37 #include "fscache.h"
38 #include "smbdirect.h"
39 #ifdef CONFIG_CIFS_DFS_UPCALL
40 #include "dfs_cache.h"
41 #endif
42 
43 #ifdef CONFIG_CIFS_POSIX
44 static struct {
45 	int index;
46 	char *name;
47 } protocols[] = {
48 	{CIFS_PROT, "\2NT LM 0.12"},
49 	{POSIX_PROT, "\2POSIX 2"},
50 	{BAD_PROT, "\2"}
51 };
52 #else
53 static struct {
54 	int index;
55 	char *name;
56 } protocols[] = {
57 	{CIFS_PROT, "\2NT LM 0.12"},
58 	{BAD_PROT, "\2"}
59 };
60 #endif
61 
62 /* define the number of elements in the cifs dialect array */
63 #ifdef CONFIG_CIFS_POSIX
64 #define CIFS_NUM_PROT 2
65 #else /* not posix */
66 #define CIFS_NUM_PROT 1
67 #endif /* CIFS_POSIX */
68 
69 
70 /* reconnect the socket, tcon, and smb session if needed */
71 static int
cifs_reconnect_tcon(struct cifs_tcon * tcon,int smb_command)72 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
73 {
74 	struct TCP_Server_Info *server;
75 	struct cifs_ses *ses;
76 	int rc;
77 
78 	/*
79 	 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
80 	 * tcp and smb session status done differently for those three - in the
81 	 * calling routine
82 	 */
83 	if (!tcon)
84 		return 0;
85 
86 	ses = tcon->ses;
87 	server = ses->server;
88 
89 	/*
90 	 * only tree disconnect, open, and write, (and ulogoff which does not
91 	 * have tcon) are allowed as we start umount
92 	 */
93 	spin_lock(&tcon->tc_lock);
94 	if (tcon->status == TID_EXITING) {
95 		if (smb_command != SMB_COM_TREE_DISCONNECT) {
96 			spin_unlock(&tcon->tc_lock);
97 			cifs_dbg(FYI, "can not send cmd %d while umounting\n",
98 				 smb_command);
99 			return -ENODEV;
100 		}
101 	}
102 	spin_unlock(&tcon->tc_lock);
103 
104 again:
105 	rc = cifs_wait_for_server_reconnect(server, tcon->retry);
106 	if (rc)
107 		return rc;
108 
109 	spin_lock(&ses->chan_lock);
110 	if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
111 		spin_unlock(&ses->chan_lock);
112 		return 0;
113 	}
114 	spin_unlock(&ses->chan_lock);
115 
116 	mutex_lock(&ses->session_mutex);
117 	/*
118 	 * Handle the case where a concurrent thread failed to negotiate or
119 	 * killed a channel.
120 	 */
121 	spin_lock(&server->srv_lock);
122 	switch (server->tcpStatus) {
123 	case CifsExiting:
124 		spin_unlock(&server->srv_lock);
125 		mutex_unlock(&ses->session_mutex);
126 		return -EHOSTDOWN;
127 	case CifsNeedReconnect:
128 		spin_unlock(&server->srv_lock);
129 		mutex_unlock(&ses->session_mutex);
130 		if (!tcon->retry)
131 			return -EHOSTDOWN;
132 		goto again;
133 	default:
134 		break;
135 	}
136 	spin_unlock(&server->srv_lock);
137 
138 	/*
139 	 * need to prevent multiple threads trying to simultaneously
140 	 * reconnect the same SMB session
141 	 */
142 	spin_lock(&ses->ses_lock);
143 	spin_lock(&ses->chan_lock);
144 	if (!cifs_chan_needs_reconnect(ses, server) &&
145 	    ses->ses_status == SES_GOOD) {
146 		spin_unlock(&ses->chan_lock);
147 		spin_unlock(&ses->ses_lock);
148 
149 		/* this means that we only need to tree connect */
150 		if (tcon->need_reconnect)
151 			goto skip_sess_setup;
152 
153 		mutex_unlock(&ses->session_mutex);
154 		goto out;
155 	}
156 	spin_unlock(&ses->chan_lock);
157 	spin_unlock(&ses->ses_lock);
158 
159 	rc = cifs_negotiate_protocol(0, ses, server);
160 	if (rc) {
161 		mutex_unlock(&ses->session_mutex);
162 		if (!tcon->retry)
163 			return -EHOSTDOWN;
164 		goto again;
165 	}
166 	rc = cifs_setup_session(0, ses, server, ses->local_nls);
167 	if ((rc == -EACCES) || (rc == -EHOSTDOWN) || (rc == -EKEYREVOKED)) {
168 		/*
169 		 * Try alternate password for next reconnect if an alternate
170 		 * password is available.
171 		 */
172 		if (ses->password2)
173 			swap(ses->password2, ses->password);
174 	}
175 
176 	/* do we need to reconnect tcon? */
177 	if (rc || !tcon->need_reconnect) {
178 		mutex_unlock(&ses->session_mutex);
179 		goto out;
180 	}
181 
182 skip_sess_setup:
183 	cifs_mark_open_files_invalid(tcon);
184 	rc = cifs_tree_connect(0, tcon);
185 	mutex_unlock(&ses->session_mutex);
186 	cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
187 
188 	if (rc) {
189 		pr_warn_once("reconnect tcon failed rc = %d\n", rc);
190 		goto out;
191 	}
192 
193 	atomic_inc(&tconInfoReconnectCount);
194 
195 	/* tell server Unix caps we support */
196 	if (cap_unix(ses))
197 		reset_cifs_unix_caps(0, tcon, NULL, NULL);
198 
199 	/*
200 	 * Removed call to reopen open files here. It is safer (and faster) to
201 	 * reopen files one at a time as needed in read and write.
202 	 *
203 	 * FIXME: what about file locks? don't we need to reclaim them ASAP?
204 	 */
205 
206 out:
207 	/*
208 	 * Check if handle based operation so we know whether we can continue
209 	 * or not without returning to caller to reset file handle
210 	 */
211 	switch (smb_command) {
212 	case SMB_COM_READ_ANDX:
213 	case SMB_COM_WRITE_ANDX:
214 	case SMB_COM_CLOSE:
215 	case SMB_COM_FIND_CLOSE2:
216 	case SMB_COM_LOCKING_ANDX:
217 		rc = -EAGAIN;
218 	}
219 
220 	return rc;
221 }
222 
223 /* Allocate and return pointer to an SMB request buffer, and set basic
224    SMB information in the SMB header.  If the return code is zero, this
225    function must have filled in request_buf pointer */
226 static int
small_smb_init(int smb_command,int wct,struct cifs_tcon * tcon,void ** request_buf)227 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
228 		void **request_buf)
229 {
230 	unsigned int in_len;
231 	int rc;
232 
233 	rc = cifs_reconnect_tcon(tcon, smb_command);
234 	if (rc)
235 		return rc;
236 
237 	*request_buf = cifs_small_buf_get();
238 	if (*request_buf == NULL) {
239 		/* BB should we add a retry in here if not a writepage? */
240 		return -ENOMEM;
241 	}
242 
243 	in_len = header_assemble((struct smb_hdr *) *request_buf, smb_command,
244 				 tcon, wct);
245 
246 	if (tcon != NULL)
247 		cifs_stats_inc(&tcon->num_smbs_sent);
248 
249 	return in_len;
250 }
251 
252 int
small_smb_init_no_tc(const int smb_command,const int wct,struct cifs_ses * ses,void ** request_buf)253 small_smb_init_no_tc(const int smb_command, const int wct,
254 		     struct cifs_ses *ses, void **request_buf)
255 {
256 	int rc;
257 	struct smb_hdr *buffer;
258 
259 	rc = small_smb_init(smb_command, wct, NULL, request_buf);
260 	if (rc < 0)
261 		return rc;
262 
263 	buffer = (struct smb_hdr *)*request_buf;
264 	buffer->Mid = get_next_mid(ses->server);
265 	if (ses->capabilities & CAP_UNICODE)
266 		buffer->Flags2 |= SMBFLG2_UNICODE;
267 	if (ses->capabilities & CAP_STATUS32)
268 		buffer->Flags2 |= SMBFLG2_ERR_STATUS;
269 
270 	/* uid, tid can stay at zero as set in header assemble */
271 
272 	/* BB add support for turning on the signing when
273 	this function is used after 1st of session setup requests */
274 
275 	return rc;
276 }
277 
278 /* If the return code is zero, this function must fill in request_buf pointer */
279 static int
__smb_init(int smb_command,int wct,struct cifs_tcon * tcon,void ** request_buf,void ** response_buf)280 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
281 			void **request_buf, void **response_buf)
282 {
283 	unsigned int in_len;
284 
285 	*request_buf = cifs_buf_get();
286 	if (*request_buf == NULL) {
287 		/* BB should we add a retry in here if not a writepage? */
288 		return -ENOMEM;
289 	}
290     /* Although the original thought was we needed the response buf for  */
291     /* potential retries of smb operations it turns out we can determine */
292     /* from the mid flags when the request buffer can be resent without  */
293     /* having to use a second distinct buffer for the response */
294 	if (response_buf)
295 		*response_buf = *request_buf;
296 
297 	in_len = header_assemble((struct smb_hdr *)*request_buf, smb_command, tcon,
298 				 wct);
299 
300 	if (tcon != NULL)
301 		cifs_stats_inc(&tcon->num_smbs_sent);
302 
303 	return in_len;
304 }
305 
306 /* If the return code is zero, this function must fill in request_buf pointer */
307 static int
smb_init(int smb_command,int wct,struct cifs_tcon * tcon,void ** request_buf,void ** response_buf)308 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
309 	 void **request_buf, void **response_buf)
310 {
311 	int rc;
312 
313 	rc = cifs_reconnect_tcon(tcon, smb_command);
314 	if (rc)
315 		return rc;
316 
317 	return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
318 }
319 
320 static int
smb_init_no_reconnect(int smb_command,int wct,struct cifs_tcon * tcon,void ** request_buf,void ** response_buf)321 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
322 			void **request_buf, void **response_buf)
323 {
324 	spin_lock(&tcon->ses->chan_lock);
325 	if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
326 	    tcon->need_reconnect) {
327 		spin_unlock(&tcon->ses->chan_lock);
328 		return -EHOSTDOWN;
329 	}
330 	spin_unlock(&tcon->ses->chan_lock);
331 
332 	return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
333 }
334 
validate_t2(struct smb_t2_rsp * pSMB)335 static int validate_t2(struct smb_t2_rsp *pSMB)
336 {
337 	unsigned int total_size;
338 
339 	/* check for plausible wct */
340 	if (pSMB->hdr.WordCount < 10)
341 		goto vt2_err;
342 
343 	/* check for parm and data offset going beyond end of smb */
344 	if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
345 	    get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
346 		goto vt2_err;
347 
348 	total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
349 	if (total_size >= 512)
350 		goto vt2_err;
351 
352 	/* check that bcc is at least as big as parms + data, and that it is
353 	 * less than negotiated smb buffer
354 	 */
355 	total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
356 	if (total_size > get_bcc(&pSMB->hdr) ||
357 	    total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
358 		goto vt2_err;
359 
360 	return 0;
361 vt2_err:
362 	cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
363 		sizeof(struct smb_t2_rsp) + 16);
364 	return -EINVAL;
365 }
366 
367 static int
decode_ext_sec_blob(struct cifs_ses * ses,SMB_NEGOTIATE_RSP * pSMBr)368 decode_ext_sec_blob(struct cifs_ses *ses, SMB_NEGOTIATE_RSP *pSMBr)
369 {
370 	int	rc = 0;
371 	u16	count;
372 	char	*guid = pSMBr->u.extended_response.GUID;
373 	struct TCP_Server_Info *server = ses->server;
374 
375 	count = get_bcc(&pSMBr->hdr);
376 	if (count < SMB1_CLIENT_GUID_SIZE)
377 		return smb_EIO2(smb_eio_trace_neg_sec_blob_too_small,
378 				count, SMB1_CLIENT_GUID_SIZE);
379 
380 	spin_lock(&cifs_tcp_ses_lock);
381 	if (server->srv_count > 1) {
382 		spin_unlock(&cifs_tcp_ses_lock);
383 		if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
384 			cifs_dbg(FYI, "server UID changed\n");
385 			memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
386 		}
387 	} else {
388 		spin_unlock(&cifs_tcp_ses_lock);
389 		memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
390 	}
391 
392 	if (count == SMB1_CLIENT_GUID_SIZE) {
393 		server->sec_ntlmssp = true;
394 	} else {
395 		count -= SMB1_CLIENT_GUID_SIZE;
396 		rc = decode_negTokenInit(
397 			pSMBr->u.extended_response.SecurityBlob, count, server);
398 		if (rc != 1)
399 			return -EINVAL;
400 	}
401 
402 	return 0;
403 }
404 
405 static bool
should_set_ext_sec_flag(enum securityEnum sectype)406 should_set_ext_sec_flag(enum securityEnum sectype)
407 {
408 	switch (sectype) {
409 	case RawNTLMSSP:
410 	case Kerberos:
411 		return true;
412 	case Unspecified:
413 		if (global_secflags &
414 		    (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
415 			return true;
416 		fallthrough;
417 	default:
418 		return false;
419 	}
420 }
421 
422 int
CIFSSMBNegotiate(const unsigned int xid,struct cifs_ses * ses,struct TCP_Server_Info * server)423 CIFSSMBNegotiate(const unsigned int xid,
424 		 struct cifs_ses *ses,
425 		 struct TCP_Server_Info *server)
426 {
427 	SMB_NEGOTIATE_REQ *pSMB;
428 	SMB_NEGOTIATE_RSP *pSMBr;
429 	unsigned int in_len;
430 	int rc = 0;
431 	int bytes_returned;
432 	int i;
433 	u16 count;
434 
435 	if (!server) {
436 		WARN(1, "%s: server is NULL!\n", __func__);
437 		return smb_EIO(smb_eio_trace_null_pointers);
438 	}
439 
440 	rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
441 		      (void **) &pSMB, (void **) &pSMBr);
442 	if (rc < 0)
443 		return rc;
444 	in_len = rc;
445 
446 	pSMB->hdr.Mid = get_next_mid(server);
447 	pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
448 
449 	if (ses->unicode != 0)
450 		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
451 
452 	if (should_set_ext_sec_flag(ses->sectype)) {
453 		cifs_dbg(FYI, "Requesting extended security\n");
454 		pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
455 	}
456 
457 	count = 0;
458 	/*
459 	 * We know that all the name entries in the protocols array
460 	 * are short (< 16 bytes anyway) and are NUL terminated.
461 	 */
462 	for (i = 0; i < CIFS_NUM_PROT; i++) {
463 		size_t len = strlen(protocols[i].name) + 1;
464 
465 		memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
466 		count += len;
467 	}
468 	in_len += count;
469 	pSMB->ByteCount = cpu_to_le16(count);
470 
471 	rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len,
472 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
473 	if (rc != 0)
474 		goto neg_err_exit;
475 
476 	server->dialect = le16_to_cpu(pSMBr->DialectIndex);
477 	cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
478 	/* Check wct = 1 error case */
479 	if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
480 		/* core returns wct = 1, but we do not ask for core - otherwise
481 		small wct just comes when dialect index is -1 indicating we
482 		could not negotiate a common dialect */
483 		rc = -EOPNOTSUPP;
484 		goto neg_err_exit;
485 	} else if (pSMBr->hdr.WordCount != 17) {
486 		/* unknown wct */
487 		rc = -EOPNOTSUPP;
488 		goto neg_err_exit;
489 	}
490 	/* else wct == 17, NTLM or better */
491 
492 	server->sec_mode = pSMBr->SecurityMode;
493 	if ((server->sec_mode & SECMODE_USER) == 0)
494 		cifs_dbg(FYI, "share mode security\n");
495 
496 	/* one byte, so no need to convert this or EncryptionKeyLen from
497 	   little endian */
498 	server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
499 			       cifs_max_pending);
500 	set_credits(server, server->maxReq);
501 	/* probably no need to store and check maxvcs */
502 	server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
503 	/* set up max_read for readahead check */
504 	server->max_read = server->maxBuf;
505 	server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
506 	cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
507 	server->capabilities = le32_to_cpu(pSMBr->Capabilities);
508 	server->session_key_id = pSMBr->SessionKey;
509 	server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
510 	server->timeAdj *= 60;
511 
512 	if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
513 		server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
514 		memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
515 		       CIFS_CRYPTO_KEY_SIZE);
516 	} else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
517 			server->capabilities & CAP_EXTENDED_SECURITY) {
518 		server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
519 		rc = decode_ext_sec_blob(ses, pSMBr);
520 	} else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
521 		/* no crypt key only if plain text pwd */
522 		rc = smb_EIO(smb_eio_trace_neg_no_crypt_key);
523 	} else {
524 		server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
525 		server->capabilities &= ~CAP_EXTENDED_SECURITY;
526 	}
527 
528 	if (!rc)
529 		rc = cifs_enable_signing(server, ses->sign);
530 neg_err_exit:
531 	cifs_buf_release(pSMB);
532 
533 	cifs_dbg(FYI, "negprot rc %d\n", rc);
534 	return rc;
535 }
536 
537 /*
538  * Issue a TREE_CONNECT request.
539  */
540 int
CIFSTCon(const unsigned int xid,struct cifs_ses * ses,const char * tree,struct cifs_tcon * tcon,const struct nls_table * nls_codepage)541 CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
542 	 const char *tree, struct cifs_tcon *tcon,
543 	 const struct nls_table *nls_codepage)
544 {
545 	struct smb_hdr *smb_buffer;
546 	struct smb_hdr *smb_buffer_response;
547 	TCONX_REQ *pSMB;
548 	TCONX_RSP *pSMBr;
549 	unsigned char *bcc_ptr;
550 	int rc = 0;
551 	int length, in_len;
552 	__u16 bytes_left, count;
553 
554 	if (ses == NULL)
555 		return smb_EIO(smb_eio_trace_null_pointers);
556 
557 	smb_buffer = cifs_buf_get();
558 	if (smb_buffer == NULL)
559 		return -ENOMEM;
560 
561 	smb_buffer_response = smb_buffer;
562 
563 	in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
564 				 NULL /*no tid */, 4 /*wct */);
565 
566 	smb_buffer->Mid = get_next_mid(ses->server);
567 	smb_buffer->Uid = ses->Suid;
568 	pSMB = (TCONX_REQ *) smb_buffer;
569 	pSMBr = (TCONX_RSP *) smb_buffer_response;
570 
571 	pSMB->AndXCommand = 0xFF;
572 	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
573 	bcc_ptr = &pSMB->Password[0];
574 
575 	pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
576 	*bcc_ptr = 0; /* password is null byte */
577 	bcc_ptr++;              /* skip password */
578 	/* already aligned so no need to do it below */
579 
580 	if (ses->server->sign)
581 		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
582 
583 	if (ses->capabilities & CAP_STATUS32)
584 		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
585 
586 	if (ses->capabilities & CAP_DFS)
587 		smb_buffer->Flags2 |= SMBFLG2_DFS;
588 
589 	if (ses->capabilities & CAP_UNICODE) {
590 		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
591 		length =
592 		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
593 			6 /* max utf8 char length in bytes */ *
594 			(/* server len*/ + 256 /* share len */), nls_codepage);
595 		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
596 		bcc_ptr += 2;	/* skip trailing null */
597 	} else {		/* ASCII */
598 		strcpy(bcc_ptr, tree);
599 		bcc_ptr += strlen(tree) + 1;
600 	}
601 	strcpy(bcc_ptr, "?????");
602 	bcc_ptr += strlen("?????");
603 	bcc_ptr += 1;
604 	count = bcc_ptr - &pSMB->Password[0];
605 	in_len += count;
606 	pSMB->ByteCount = cpu_to_le16(count);
607 
608 	rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response,
609 			 &length, 0);
610 
611 	/* above now done in SendReceive */
612 	if (rc == 0) {
613 		bool is_unicode;
614 
615 		tcon->tid = smb_buffer_response->Tid;
616 		bcc_ptr = pByteArea(smb_buffer_response);
617 		bytes_left = get_bcc(smb_buffer_response);
618 		length = strnlen(bcc_ptr, bytes_left - 2);
619 		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
620 			is_unicode = true;
621 		else
622 			is_unicode = false;
623 
624 
625 		/* skip service field (NB: this field is always ASCII) */
626 		if (length == 3) {
627 			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
628 			    (bcc_ptr[2] == 'C')) {
629 				cifs_dbg(FYI, "IPC connection\n");
630 				tcon->ipc = true;
631 				tcon->pipe = true;
632 			}
633 		} else if (length == 2) {
634 			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
635 				/* the most common case */
636 				cifs_dbg(FYI, "disk share connection\n");
637 			}
638 		}
639 		bcc_ptr += length + 1;
640 		bytes_left -= (length + 1);
641 		strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
642 
643 		/* mostly informational -- no need to fail on error here */
644 		kfree(tcon->nativeFileSystem);
645 		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
646 						      bytes_left, is_unicode,
647 						      nls_codepage);
648 
649 		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
650 
651 		if ((smb_buffer_response->WordCount == 3) ||
652 			 (smb_buffer_response->WordCount == 7))
653 			/* field is in same location */
654 			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
655 		else
656 			tcon->Flags = 0;
657 		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
658 
659 		/*
660 		 * reset_cifs_unix_caps calls QFSInfo which requires
661 		 * need_reconnect to be false, but we would not need to call
662 		 * reset_caps if this were not a reconnect case so must check
663 		 * need_reconnect flag here.  The caller will also clear
664 		 * need_reconnect when tcon was successful but needed to be
665 		 * cleared earlier in the case of unix extensions reconnect
666 		 */
667 		if (tcon->need_reconnect && tcon->unix_ext) {
668 			cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
669 			tcon->need_reconnect = false;
670 			reset_cifs_unix_caps(xid, tcon, NULL, NULL);
671 		}
672 	}
673 	cifs_buf_release(smb_buffer);
674 	return rc;
675 }
676 
677 int
CIFSSMBTDis(const unsigned int xid,struct cifs_tcon * tcon)678 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
679 {
680 	struct smb_hdr *smb_buffer;
681 	unsigned int in_len;
682 	int rc = 0;
683 
684 	cifs_dbg(FYI, "In tree disconnect\n");
685 
686 	/* BB: do we need to check this? These should never be NULL. */
687 	if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
688 		return smb_EIO(smb_eio_trace_null_pointers);
689 
690 	/*
691 	 * No need to return error on this operation if tid invalidated and
692 	 * closed on server already e.g. due to tcp session crashing. Also,
693 	 * the tcon is no longer on the list, so no need to take lock before
694 	 * checking this.
695 	 */
696 	spin_lock(&tcon->ses->chan_lock);
697 	if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
698 		spin_unlock(&tcon->ses->chan_lock);
699 		return smb_EIO(smb_eio_trace_tdis_in_reconnect);
700 	}
701 	spin_unlock(&tcon->ses->chan_lock);
702 
703 	rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
704 			    (void **)&smb_buffer);
705 	if (rc < 0)
706 		return rc;
707 	in_len = rc;
708 
709 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, in_len, 0);
710 	cifs_small_buf_release(smb_buffer);
711 	if (rc)
712 		cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
713 
714 	/* No need to return error on this operation if tid invalidated and
715 	   closed on server already e.g. due to tcp session crashing */
716 	if (rc == -EAGAIN)
717 		rc = 0;
718 
719 	return rc;
720 }
721 
722 /*
723  * This is a no-op for now. We're not really interested in the reply, but
724  * rather in the fact that the server sent one and that server->lstrp
725  * gets updated.
726  *
727  * FIXME: maybe we should consider checking that the reply matches request?
728  */
729 static void
cifs_echo_callback(struct TCP_Server_Info * server,struct mid_q_entry * mid)730 cifs_echo_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid)
731 {
732 	struct cifs_credits credits = { .value = 1, .instance = 0 };
733 
734 	release_mid(server, mid);
735 	add_credits(server, &credits, CIFS_ECHO_OP);
736 }
737 
738 int
CIFSSMBEcho(struct TCP_Server_Info * server)739 CIFSSMBEcho(struct TCP_Server_Info *server)
740 {
741 	ECHO_REQ *smb;
742 	int rc = 0;
743 	struct kvec iov[1];
744 	struct smb_rqst rqst = {
745 		.rq_iov = iov,
746 		.rq_nvec = ARRAY_SIZE(iov),
747 	};
748 	unsigned int in_len;
749 
750 	cifs_dbg(FYI, "In echo request\n");
751 
752 	rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
753 	if (rc < 0)
754 		return rc;
755 	in_len = rc;
756 
757 	if (server->capabilities & CAP_UNICODE)
758 		smb->hdr.Flags2 |= SMBFLG2_UNICODE;
759 
760 	/* set up echo request */
761 	smb->hdr.Tid = 0xffff;
762 	smb->hdr.WordCount = 1;
763 	put_unaligned_le16(1, &smb->EchoCount);
764 	put_bcc(1, &smb->hdr);
765 	smb->Data[0] = 'a';
766 	in_len += 3;
767 
768 	iov[0].iov_len = in_len;
769 	iov[0].iov_base = smb;
770 
771 	rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
772 			     server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
773 	if (rc)
774 		cifs_dbg(FYI, "Echo request failed: %d\n", rc);
775 
776 	cifs_small_buf_release(smb);
777 
778 	return rc;
779 }
780 
781 int
CIFSSMBLogoff(const unsigned int xid,struct cifs_ses * ses)782 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
783 {
784 	LOGOFF_ANDX_REQ *pSMB;
785 	unsigned int in_len;
786 	int rc = 0;
787 
788 	cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
789 
790 	/*
791 	 * BB: do we need to check validity of ses and server? They should
792 	 * always be valid since we have an active reference. If not, that
793 	 * should probably be a BUG()
794 	 */
795 	if (!ses || !ses->server)
796 		return smb_EIO(smb_eio_trace_null_pointers);
797 
798 	mutex_lock(&ses->session_mutex);
799 	spin_lock(&ses->chan_lock);
800 	if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
801 		spin_unlock(&ses->chan_lock);
802 		goto session_already_dead; /* no need to send SMBlogoff if uid
803 					      already closed due to reconnect */
804 	}
805 	spin_unlock(&ses->chan_lock);
806 
807 	rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
808 	if (rc < 0) {
809 		mutex_unlock(&ses->session_mutex);
810 		return rc;
811 	}
812 	in_len = rc;
813 
814 	pSMB->hdr.Mid = get_next_mid(ses->server);
815 
816 	if (ses->server->sign)
817 		pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
818 
819 	pSMB->hdr.Uid = ses->Suid;
820 
821 	pSMB->AndXCommand = 0xFF;
822 	rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, in_len, 0);
823 	cifs_small_buf_release(pSMB);
824 session_already_dead:
825 	mutex_unlock(&ses->session_mutex);
826 
827 	/* if session dead then we do not need to do ulogoff,
828 		since server closed smb session, no sense reporting
829 		error */
830 	if (rc == -EAGAIN)
831 		rc = 0;
832 	return rc;
833 }
834 
835 int
CIFSPOSIXDelFile(const unsigned int xid,struct cifs_tcon * tcon,const char * fileName,__u16 type,const struct nls_table * nls_codepage,int remap)836 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
837 		 const char *fileName, __u16 type,
838 		 const struct nls_table *nls_codepage, int remap)
839 {
840 	TRANSACTION2_SPI_REQ *pSMB = NULL;
841 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
842 	struct unlink_psx_rq *pRqD;
843 	unsigned int in_len;
844 	int name_len;
845 	int rc = 0;
846 	int bytes_returned = 0;
847 	__u16 params, param_offset, offset, byte_count;
848 
849 	cifs_dbg(FYI, "In POSIX delete\n");
850 PsxDelete:
851 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
852 		      (void **) &pSMBr);
853 	if (rc < 0)
854 		return rc;
855 	in_len = rc;
856 
857 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
858 		name_len =
859 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
860 				       PATH_MAX, nls_codepage, remap);
861 		name_len++;	/* trailing null */
862 		name_len *= 2;
863 	} else {
864 		name_len = copy_path_name(pSMB->FileName, fileName);
865 	}
866 
867 	params = 6 + name_len;
868 	pSMB->MaxParameterCount = cpu_to_le16(2);
869 	pSMB->MaxDataCount = 0; /* BB double check this with jra */
870 	pSMB->MaxSetupCount = 0;
871 	pSMB->Reserved = 0;
872 	pSMB->Flags = 0;
873 	pSMB->Timeout = 0;
874 	pSMB->Reserved2 = 0;
875 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
876 				InformationLevel);
877 	offset = param_offset + params;
878 
879 	/* Setup pointer to Request Data (inode type). */
880 	pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset);
881 	pRqD->type = cpu_to_le16(type);
882 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
883 	pSMB->DataOffset = cpu_to_le16(offset);
884 	pSMB->SetupCount = 1;
885 	pSMB->Reserved3 = 0;
886 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
887 	byte_count = 3 /* pad */  + params + sizeof(struct unlink_psx_rq);
888 
889 	pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
890 	pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
891 	pSMB->ParameterCount = cpu_to_le16(params);
892 	pSMB->TotalParameterCount = pSMB->ParameterCount;
893 	pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
894 	pSMB->Reserved4 = 0;
895 	in_len += byte_count;
896 	pSMB->ByteCount = cpu_to_le16(byte_count);
897 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
898 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
899 	if (rc)
900 		cifs_dbg(FYI, "Posix delete returned %d\n", rc);
901 	cifs_buf_release(pSMB);
902 
903 	cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
904 
905 	if (rc == -EAGAIN)
906 		goto PsxDelete;
907 
908 	return rc;
909 }
910 
911 int
CIFSSMBDelFile(const unsigned int xid,struct cifs_tcon * tcon,const char * name,struct cifs_sb_info * cifs_sb,struct dentry * dentry)912 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
913 	       struct cifs_sb_info *cifs_sb, struct dentry *dentry)
914 {
915 	DELETE_FILE_REQ *pSMB = NULL;
916 	DELETE_FILE_RSP *pSMBr = NULL;
917 	unsigned int in_len;
918 	int rc = 0;
919 	int bytes_returned;
920 	int name_len;
921 	int remap = cifs_remap(cifs_sb);
922 
923 DelFileRetry:
924 	rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
925 		      (void **) &pSMBr);
926 	if (rc < 0)
927 		return rc;
928 	in_len = rc;
929 
930 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
931 		name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
932 					      PATH_MAX, cifs_sb->local_nls,
933 					      remap);
934 		name_len++;	/* trailing null */
935 		name_len *= 2;
936 	} else {
937 		name_len = copy_path_name(pSMB->fileName, name);
938 	}
939 	pSMB->SearchAttributes =
940 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
941 	pSMB->BufferFormat = 0x04;
942 	in_len += name_len + 1;
943 	pSMB->ByteCount = cpu_to_le16(name_len + 1);
944 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
945 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
946 	cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
947 	if (rc)
948 		cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
949 
950 	cifs_buf_release(pSMB);
951 	if (rc == -EAGAIN)
952 		goto DelFileRetry;
953 
954 	return rc;
955 }
956 
957 int
CIFSSMBRmDir(const unsigned int xid,struct cifs_tcon * tcon,const char * name,struct cifs_sb_info * cifs_sb)958 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
959 	     struct cifs_sb_info *cifs_sb)
960 {
961 	DELETE_DIRECTORY_REQ *pSMB = NULL;
962 	DELETE_DIRECTORY_RSP *pSMBr = NULL;
963 	unsigned int in_len;
964 	int rc = 0;
965 	int bytes_returned;
966 	int name_len;
967 	int remap = cifs_remap(cifs_sb);
968 
969 	cifs_dbg(FYI, "In CIFSSMBRmDir\n");
970 RmDirRetry:
971 	rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
972 		      (void **) &pSMBr);
973 	if (rc < 0)
974 		return rc;
975 	in_len = rc;
976 
977 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
978 		name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
979 					      PATH_MAX, cifs_sb->local_nls,
980 					      remap);
981 		name_len++;	/* trailing null */
982 		name_len *= 2;
983 	} else {
984 		name_len = copy_path_name(pSMB->DirName, name);
985 	}
986 
987 	pSMB->BufferFormat = 0x04;
988 	in_len += name_len + 1;
989 	pSMB->ByteCount = cpu_to_le16(name_len + 1);
990 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
991 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
992 	cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
993 	if (rc)
994 		cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
995 
996 	cifs_buf_release(pSMB);
997 	if (rc == -EAGAIN)
998 		goto RmDirRetry;
999 	return rc;
1000 }
1001 
1002 int
CIFSSMBMkDir(const unsigned int xid,struct inode * inode,umode_t mode,struct cifs_tcon * tcon,const char * name,struct cifs_sb_info * cifs_sb)1003 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
1004 	     struct cifs_tcon *tcon, const char *name,
1005 	     struct cifs_sb_info *cifs_sb)
1006 {
1007 	int rc = 0;
1008 	CREATE_DIRECTORY_REQ *pSMB = NULL;
1009 	CREATE_DIRECTORY_RSP *pSMBr = NULL;
1010 	unsigned int in_len;
1011 	int bytes_returned;
1012 	int name_len;
1013 	int remap = cifs_remap(cifs_sb);
1014 
1015 	cifs_dbg(FYI, "In CIFSSMBMkDir\n");
1016 MkDirRetry:
1017 	rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
1018 		      (void **) &pSMBr);
1019 	if (rc < 0)
1020 		return rc;
1021 	in_len = rc;
1022 
1023 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1024 		name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
1025 					      PATH_MAX, cifs_sb->local_nls,
1026 					      remap);
1027 		name_len++;	/* trailing null */
1028 		name_len *= 2;
1029 	} else {
1030 		name_len = copy_path_name(pSMB->DirName, name);
1031 	}
1032 
1033 	pSMB->BufferFormat = 0x04;
1034 	in_len += name_len + 1;
1035 	pSMB->ByteCount = cpu_to_le16(name_len + 1);
1036 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
1037 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1038 	cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1039 	if (rc)
1040 		cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
1041 
1042 	cifs_buf_release(pSMB);
1043 	if (rc == -EAGAIN)
1044 		goto MkDirRetry;
1045 	return rc;
1046 }
1047 
1048 int
CIFSPOSIXCreate(const unsigned int xid,struct cifs_tcon * tcon,__u32 posix_flags,__u64 mode,__u16 * netfid,FILE_UNIX_BASIC_INFO * pRetData,__u32 * pOplock,const char * name,const struct nls_table * nls_codepage,int remap)1049 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1050 		__u32 posix_flags, __u64 mode, __u16 *netfid,
1051 		FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1052 		const char *name, const struct nls_table *nls_codepage,
1053 		int remap)
1054 {
1055 	TRANSACTION2_SPI_REQ *pSMB = NULL;
1056 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
1057 	unsigned int in_len;
1058 	int name_len;
1059 	int rc = 0;
1060 	int bytes_returned = 0;
1061 	__u16 params, param_offset, offset, byte_count, count;
1062 	OPEN_PSX_REQ *pdata;
1063 	OPEN_PSX_RSP *psx_rsp;
1064 
1065 	cifs_dbg(FYI, "In POSIX Create\n");
1066 PsxCreat:
1067 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1068 		      (void **) &pSMBr);
1069 	if (rc < 0)
1070 		return rc;
1071 	in_len = rc;
1072 
1073 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1074 		name_len =
1075 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1076 				       PATH_MAX, nls_codepage, remap);
1077 		name_len++;	/* trailing null */
1078 		name_len *= 2;
1079 	} else {
1080 		name_len = copy_path_name(pSMB->FileName, name);
1081 	}
1082 
1083 	params = 6 + name_len;
1084 	count = sizeof(OPEN_PSX_REQ);
1085 	pSMB->MaxParameterCount = cpu_to_le16(2);
1086 	pSMB->MaxDataCount = cpu_to_le16(1000);	/* large enough */
1087 	pSMB->MaxSetupCount = 0;
1088 	pSMB->Reserved = 0;
1089 	pSMB->Flags = 0;
1090 	pSMB->Timeout = 0;
1091 	pSMB->Reserved2 = 0;
1092 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
1093 				InformationLevel);
1094 	offset = param_offset + params;
1095 	pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset);
1096 	pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1097 	pdata->Permissions = cpu_to_le64(mode);
1098 	pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1099 	pdata->OpenFlags =  cpu_to_le32(*pOplock);
1100 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
1101 	pSMB->DataOffset = cpu_to_le16(offset);
1102 	pSMB->SetupCount = 1;
1103 	pSMB->Reserved3 = 0;
1104 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1105 	byte_count = 3 /* pad */  + params + count;
1106 
1107 	pSMB->DataCount = cpu_to_le16(count);
1108 	pSMB->ParameterCount = cpu_to_le16(params);
1109 	pSMB->TotalDataCount = pSMB->DataCount;
1110 	pSMB->TotalParameterCount = pSMB->ParameterCount;
1111 	pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1112 	pSMB->Reserved4 = 0;
1113 	in_len += byte_count;
1114 	pSMB->ByteCount = cpu_to_le16(byte_count);
1115 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
1116 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1117 	if (rc) {
1118 		cifs_dbg(FYI, "Posix create returned %d\n", rc);
1119 		goto psx_create_err;
1120 	}
1121 
1122 	cifs_dbg(FYI, "copying inode info\n");
1123 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1124 
1125 	if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1126 		rc = smb_EIO2(smb_eio_trace_create_rsp_too_small,
1127 			      get_bcc(&pSMBr->hdr), sizeof(OPEN_PSX_RSP));
1128 		goto psx_create_err;
1129 	}
1130 
1131 	/* copy return information to pRetData */
1132 	psx_rsp = (OPEN_PSX_RSP *)
1133 		((char *)pSMBr + le16_to_cpu(pSMBr->t2.DataOffset));
1134 
1135 	*pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1136 	if (netfid)
1137 		*netfid = psx_rsp->Fid;   /* cifs fid stays in le */
1138 	/* Let caller know file was created so we can set the mode. */
1139 	/* Do we care about the CreateAction in any other cases? */
1140 	if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1141 		*pOplock |= CIFS_CREATE_ACTION;
1142 	/* check to make sure response data is there */
1143 	if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1144 		pRetData->Type = cpu_to_le32(-1); /* unknown */
1145 		cifs_dbg(NOISY, "unknown type\n");
1146 	} else {
1147 		if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1148 					+ sizeof(FILE_UNIX_BASIC_INFO)) {
1149 			cifs_dbg(VFS, "Open response data too small\n");
1150 			pRetData->Type = cpu_to_le32(-1);
1151 			goto psx_create_err;
1152 		}
1153 		memcpy(pRetData,
1154 		       (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1155 		       sizeof(*pRetData));
1156 	}
1157 
1158 psx_create_err:
1159 	cifs_buf_release(pSMB);
1160 
1161 	if (posix_flags & SMB_O_DIRECTORY)
1162 		cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1163 	else
1164 		cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1165 
1166 	if (rc == -EAGAIN)
1167 		goto PsxCreat;
1168 
1169 	return rc;
1170 }
1171 
convert_disposition(int disposition)1172 static __u16 convert_disposition(int disposition)
1173 {
1174 	__u16 ofun = 0;
1175 
1176 	switch (disposition) {
1177 		case FILE_SUPERSEDE:
1178 			ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1179 			break;
1180 		case FILE_OPEN:
1181 			ofun = SMBOPEN_OAPPEND;
1182 			break;
1183 		case FILE_CREATE:
1184 			ofun = SMBOPEN_OCREATE;
1185 			break;
1186 		case FILE_OPEN_IF:
1187 			ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1188 			break;
1189 		case FILE_OVERWRITE:
1190 			ofun = SMBOPEN_OTRUNC;
1191 			break;
1192 		case FILE_OVERWRITE_IF:
1193 			ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1194 			break;
1195 		default:
1196 			cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1197 			ofun =  SMBOPEN_OAPPEND; /* regular open */
1198 	}
1199 	return ofun;
1200 }
1201 
1202 static int
access_flags_to_smbopen_mode(const int access_flags)1203 access_flags_to_smbopen_mode(const int access_flags)
1204 {
1205 	/*
1206 	 * SYSTEM_SECURITY grants both read and write access to SACL, treat is as read/write.
1207 	 * MAXIMUM_ALLOWED grants as many access as possible, so treat it as read/write too.
1208 	 * SYNCHRONIZE as is does not grant any specific access, so do not check its mask.
1209 	 * If only SYNCHRONIZE bit is specified then fallback to read access.
1210 	 */
1211 	bool with_write_flags = access_flags & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA |
1212 						FILE_DELETE_CHILD | FILE_WRITE_ATTRIBUTES | DELETE |
1213 						WRITE_DAC | WRITE_OWNER | SYSTEM_SECURITY |
1214 						MAXIMUM_ALLOWED | GENERIC_WRITE | GENERIC_ALL);
1215 	bool with_read_flags = access_flags & (FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE |
1216 						FILE_READ_ATTRIBUTES | READ_CONTROL |
1217 						SYSTEM_SECURITY | MAXIMUM_ALLOWED | GENERIC_ALL |
1218 						GENERIC_EXECUTE | GENERIC_READ);
1219 	bool with_execute_flags = access_flags & (FILE_EXECUTE | MAXIMUM_ALLOWED | GENERIC_ALL |
1220 						GENERIC_EXECUTE);
1221 
1222 	if (with_write_flags && with_read_flags)
1223 		return SMBOPEN_READWRITE;
1224 	else if (with_write_flags)
1225 		return SMBOPEN_WRITE;
1226 	else if (with_execute_flags)
1227 		return SMBOPEN_EXECUTE;
1228 	else
1229 		return SMBOPEN_READ;
1230 }
1231 
1232 int
SMBLegacyOpen(const unsigned int xid,struct cifs_tcon * tcon,const char * fileName,const int openDisposition,const int access_flags,const int create_options,__u16 * netfid,int * pOplock,FILE_ALL_INFO * pfile_info,const struct nls_table * nls_codepage,int remap)1233 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1234 	    const char *fileName, const int openDisposition,
1235 	    const int access_flags, const int create_options, __u16 *netfid,
1236 	    int *pOplock, FILE_ALL_INFO *pfile_info,
1237 	    const struct nls_table *nls_codepage, int remap)
1238 {
1239 	int rc;
1240 	OPENX_REQ *pSMB = NULL;
1241 	OPENX_RSP *pSMBr = NULL;
1242 	unsigned int in_len;
1243 	int bytes_returned;
1244 	int name_len;
1245 	__u16 count;
1246 
1247 OldOpenRetry:
1248 	rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1249 		      (void **) &pSMBr);
1250 	if (rc < 0)
1251 		return rc;
1252 	in_len = rc;
1253 
1254 	pSMB->AndXCommand = 0xFF;       /* none */
1255 
1256 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1257 		count = 1;      /* account for one byte pad to word boundary */
1258 		name_len =
1259 		   cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1260 				      fileName, PATH_MAX, nls_codepage, remap);
1261 		name_len++;     /* trailing null */
1262 		name_len *= 2;
1263 	} else {
1264 		count = 0;      /* no pad */
1265 		name_len = copy_path_name(pSMB->fileName, fileName);
1266 	}
1267 	if (*pOplock & REQ_OPLOCK)
1268 		pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1269 	else if (*pOplock & REQ_BATCHOPLOCK)
1270 		pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1271 
1272 	pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1273 	pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1274 	pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1275 	/* set file as system file if special file such as fifo,
1276 	 * socket, char or block and server expecting SFU style and
1277 	   no Unix extensions */
1278 
1279 	if (create_options & CREATE_OPTION_SPECIAL)
1280 		pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1281 	else /* BB FIXME BB */
1282 		pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1283 
1284 	if (create_options & CREATE_OPTION_READONLY)
1285 		pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1286 
1287 	/* BB FIXME BB */
1288 /*	pSMB->CreateOptions = cpu_to_le32(create_options &
1289 						 CREATE_OPTIONS_MASK); */
1290 	/* BB FIXME END BB */
1291 
1292 	pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1293 	pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1294 	count += name_len;
1295 	in_len += count;
1296 
1297 	pSMB->ByteCount = cpu_to_le16(count);
1298 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
1299 			(struct smb_hdr *)pSMBr, &bytes_returned, 0);
1300 	cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1301 	if (rc) {
1302 		cifs_dbg(FYI, "Error in Open = %d\n", rc);
1303 	} else {
1304 	/* BB verify if wct == 15 */
1305 
1306 /*		*pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1307 
1308 		*netfid = pSMBr->Fid;   /* cifs fid stays in le */
1309 		/* Let caller know file was created so we can set the mode. */
1310 		/* Do we care about the CreateAction in any other cases? */
1311 	/* BB FIXME BB */
1312 /*		if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1313 			*pOplock |= CIFS_CREATE_ACTION; */
1314 	/* BB FIXME END */
1315 
1316 		if (pfile_info) {
1317 			pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1318 			pfile_info->LastAccessTime = 0; /* BB fixme */
1319 			pfile_info->LastWriteTime = 0; /* BB fixme */
1320 			pfile_info->ChangeTime = 0;  /* BB fixme */
1321 			pfile_info->Attributes =
1322 				cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1323 			/* the file_info buf is endian converted by caller */
1324 			pfile_info->AllocationSize =
1325 				cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1326 			pfile_info->EndOfFile = pfile_info->AllocationSize;
1327 			pfile_info->NumberOfLinks = cpu_to_le32(1);
1328 			pfile_info->DeletePending = 0; /* successful open = not delete pending */
1329 		}
1330 	}
1331 
1332 	cifs_buf_release(pSMB);
1333 	if (rc == -EAGAIN)
1334 		goto OldOpenRetry;
1335 	return rc;
1336 }
1337 
1338 int
CIFS_open(const unsigned int xid,struct cifs_open_parms * oparms,int * oplock,FILE_ALL_INFO * buf)1339 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1340 	  FILE_ALL_INFO *buf)
1341 {
1342 	int rc;
1343 	OPEN_REQ *req = NULL;
1344 	OPEN_RSP *rsp = NULL;
1345 	int bytes_returned;
1346 	int name_len;
1347 	__u16 count;
1348 	struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1349 	struct cifs_tcon *tcon = oparms->tcon;
1350 	int remap = cifs_remap(cifs_sb);
1351 	const struct nls_table *nls = cifs_sb->local_nls;
1352 	int create_options = oparms->create_options;
1353 	int desired_access = oparms->desired_access;
1354 	int disposition = oparms->disposition;
1355 	const char *path = oparms->path;
1356 	unsigned int in_len;
1357 
1358 openRetry:
1359 	rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1360 		      (void **)&rsp);
1361 	if (rc < 0)
1362 		return rc;
1363 	in_len = rc;
1364 
1365 	/* no commands go after this */
1366 	req->AndXCommand = 0xFF;
1367 
1368 	if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1369 		/* account for one byte pad to word boundary */
1370 		count = 1;
1371 		name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1372 					      path, PATH_MAX, nls, remap);
1373 		/* trailing null */
1374 		name_len++;
1375 		name_len *= 2;
1376 		req->NameLength = cpu_to_le16(name_len);
1377 	} else {
1378 		/* BB improve check for buffer overruns BB */
1379 		/* no pad */
1380 		count = 0;
1381 		name_len = copy_path_name(req->fileName, path);
1382 		req->NameLength = cpu_to_le16(name_len);
1383 	}
1384 
1385 	if (*oplock & REQ_OPLOCK)
1386 		req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1387 	else if (*oplock & REQ_BATCHOPLOCK)
1388 		req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1389 
1390 	req->DesiredAccess = cpu_to_le32(desired_access);
1391 	req->AllocationSize = 0;
1392 
1393 	/*
1394 	 * Set file as system file if special file such as fifo, socket, char
1395 	 * or block and server expecting SFU style and no Unix extensions.
1396 	 */
1397 	if (create_options & CREATE_OPTION_SPECIAL)
1398 		req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1399 	else
1400 		req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1401 
1402 	/*
1403 	 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1404 	 * sensitive checks for other servers such as Samba.
1405 	 */
1406 	if (tcon->ses->capabilities & CAP_UNIX)
1407 		req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1408 
1409 	if (create_options & CREATE_OPTION_READONLY)
1410 		req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1411 
1412 	req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1413 	req->CreateDisposition = cpu_to_le32(disposition);
1414 	req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1415 
1416 	/* BB Experiment with various impersonation levels and verify */
1417 	req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1418 	req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1419 
1420 	count += name_len;
1421 	in_len += count;
1422 
1423 	req->ByteCount = cpu_to_le16(count);
1424 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req, in_len,
1425 			 (struct smb_hdr *)rsp, &bytes_returned, 0);
1426 	cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1427 	if (rc) {
1428 		cifs_dbg(FYI, "Error in Open = %d\n", rc);
1429 		cifs_buf_release(req);
1430 		if (rc == -EAGAIN)
1431 			goto openRetry;
1432 		return rc;
1433 	}
1434 
1435 	/* 1 byte no need to le_to_cpu */
1436 	*oplock = rsp->OplockLevel;
1437 	/* cifs fid stays in le */
1438 	oparms->fid->netfid = rsp->Fid;
1439 	oparms->fid->access = desired_access;
1440 
1441 	/* Let caller know file was created so we can set the mode. */
1442 	/* Do we care about the CreateAction in any other cases? */
1443 	if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1444 		*oplock |= CIFS_CREATE_ACTION;
1445 
1446 	if (buf) {
1447 		/* copy commonly used attributes */
1448 		memcpy(&buf->common_attributes,
1449 		       &rsp->common_attributes,
1450 		       sizeof(buf->common_attributes));
1451 		/* the file_info buf is endian converted by caller */
1452 		buf->AllocationSize = rsp->AllocationSize;
1453 		buf->EndOfFile = rsp->EndOfFile;
1454 		buf->NumberOfLinks = cpu_to_le32(1);
1455 		buf->DeletePending = 0; /* successful open = not delete pending */
1456 	}
1457 
1458 	cifs_buf_release(req);
1459 	return rc;
1460 }
1461 
1462 static void
cifs_readv_callback(struct TCP_Server_Info * server,struct mid_q_entry * mid)1463 cifs_readv_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1464 {
1465 	struct cifs_io_subrequest *rdata = mid->callback_data;
1466 	struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
1467 	struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
1468 	struct inode *inode = &ictx->inode;
1469 	struct smb_rqst rqst = { .rq_iov = rdata->iov,
1470 				 .rq_nvec = 1,
1471 				 .rq_iter = rdata->subreq.io_iter };
1472 	struct cifs_credits credits = {
1473 		.value = 1,
1474 		.instance = 0,
1475 		.rreq_debug_id = rdata->rreq->debug_id,
1476 		.rreq_debug_index = rdata->subreq.debug_index,
1477 	};
1478 	unsigned int rreq_debug_id = rdata->rreq->debug_id;
1479 	unsigned int subreq_debug_index = rdata->subreq.debug_index;
1480 
1481 	cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
1482 		 __func__, mid->mid, mid->mid_state, rdata->result,
1483 		 rdata->subreq.len);
1484 
1485 	switch (mid->mid_state) {
1486 	case MID_RESPONSE_RECEIVED:
1487 		/* result already set, check signature */
1488 		if (server->sign) {
1489 			int rc = 0;
1490 
1491 			iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
1492 			rc = cifs_verify_signature(&rqst, server,
1493 						  mid->sequence_number);
1494 			if (rc)
1495 				cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1496 					 rc);
1497 		}
1498 		/* FIXME: should this be counted toward the initiating task? */
1499 		task_io_account_read(rdata->got_bytes);
1500 		cifs_stats_bytes_read(tcon, rdata->got_bytes);
1501 		break;
1502 	case MID_REQUEST_SUBMITTED:
1503 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_req_submitted);
1504 		goto do_retry;
1505 	case MID_RETRY_NEEDED:
1506 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_retry_needed);
1507 do_retry:
1508 		__set_bit(NETFS_SREQ_NEED_RETRY, &rdata->subreq.flags);
1509 		rdata->result = -EAGAIN;
1510 		if (server->sign && rdata->got_bytes)
1511 			/* reset bytes number since we can not check a sign */
1512 			rdata->got_bytes = 0;
1513 		/* FIXME: should this be counted toward the initiating task? */
1514 		task_io_account_read(rdata->got_bytes);
1515 		cifs_stats_bytes_read(tcon, rdata->got_bytes);
1516 		break;
1517 	case MID_RESPONSE_MALFORMED:
1518 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed);
1519 		rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed);
1520 		break;
1521 	default:
1522 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown);
1523 		rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown,
1524 					 mid->mid_state);
1525 		break;
1526 	}
1527 
1528 	if (rdata->result == -ENODATA) {
1529 		rdata->result = 0;
1530 		__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1531 		trace_smb3_read_err(rdata->rreq->debug_id,
1532 				    rdata->subreq.debug_index,
1533 				    rdata->xid,
1534 				    rdata->req->cfile->fid.persistent_fid,
1535 				    tcon->tid, tcon->ses->Suid,
1536 				    rdata->subreq.start + rdata->subreq.transferred,
1537 				    rdata->subreq.len   - rdata->subreq.transferred,
1538 				    rdata->result);
1539 	} else {
1540 		size_t trans = rdata->subreq.transferred + rdata->got_bytes;
1541 		if (trans < rdata->subreq.len &&
1542 		    rdata->subreq.start + trans >= netfs_read_remote_i_size(inode)) {
1543 			rdata->result = 0;
1544 			__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1545 		} else if (rdata->got_bytes > 0) {
1546 			__set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags);
1547 		}
1548 		if (rdata->got_bytes)
1549 			__set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags);
1550 		trace_smb3_read_done(rdata->rreq->debug_id,
1551 				     rdata->subreq.debug_index,
1552 				     rdata->xid,
1553 				     rdata->req->cfile->fid.persistent_fid,
1554 				     tcon->tid, tcon->ses->Suid,
1555 				     rdata->subreq.start + rdata->subreq.transferred,
1556 				     rdata->got_bytes);
1557 	}
1558 
1559 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value,
1560 			      server->credits, server->in_flight,
1561 			      0, cifs_trace_rw_credits_read_response_clear);
1562 	rdata->credits.value = 0;
1563 	rdata->subreq.error = rdata->result;
1564 	rdata->subreq.transferred += rdata->got_bytes;
1565 	trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress);
1566 	netfs_read_subreq_terminated(&rdata->subreq);
1567 	release_mid(server, mid);
1568 	add_credits(server, &credits, 0);
1569 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
1570 			      server->credits, server->in_flight,
1571 			      credits.value, cifs_trace_rw_credits_read_response_add);
1572 }
1573 
1574 /* cifs_async_readv - send an async write, and set up mid to handle result */
1575 int
cifs_async_readv(struct cifs_io_subrequest * rdata)1576 cifs_async_readv(struct cifs_io_subrequest *rdata)
1577 {
1578 	int rc;
1579 	READ_REQ *smb = NULL;
1580 	int wct;
1581 	struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
1582 	struct smb_rqst rqst = { .rq_iov = rdata->iov,
1583 				 .rq_nvec = 1 };
1584 	unsigned int in_len;
1585 
1586 	cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n",
1587 		 __func__, rdata->subreq.start, rdata->subreq.len);
1588 
1589 	if (tcon->ses->capabilities & CAP_LARGE_FILES)
1590 		wct = 12;
1591 	else {
1592 		wct = 10; /* old style read */
1593 		if ((rdata->subreq.start >> 32) > 0)  {
1594 			/* can not handle this big offset for old */
1595 			return smb_EIO(smb_eio_trace_read_too_far);
1596 		}
1597 	}
1598 
1599 	rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1600 	if (rc < 0)
1601 		return rc;
1602 	in_len = rc;
1603 
1604 	smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid);
1605 	smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16));
1606 
1607 	smb->AndXCommand = 0xFF;	/* none */
1608 	smb->Fid = rdata->req->cfile->fid.netfid;
1609 	smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
1610 	if (wct == 12)
1611 		smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
1612 	smb->Remaining = 0;
1613 	smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF);
1614 	smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16);
1615 	if (wct == 12)
1616 		smb->ByteCount = 0;
1617 	else {
1618 		/* old style read */
1619 		struct smb_com_readx_req *smbr =
1620 			(struct smb_com_readx_req *)smb;
1621 		smbr->ByteCount = 0;
1622 	}
1623 
1624 	/* 4 for RFC1001 length + 1 for BCC */
1625 	rdata->iov[0].iov_base = smb;
1626 	rdata->iov[0].iov_len = in_len;
1627 
1628 	trace_smb3_read_enter(rdata->rreq->debug_id,
1629 			      rdata->subreq.debug_index,
1630 			      rdata->xid,
1631 			      rdata->req->cfile->fid.netfid,
1632 			      tcon->tid, tcon->ses->Suid,
1633 			      rdata->subreq.start, rdata->subreq.len);
1634 
1635 	rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1636 			     cifs_readv_callback, NULL, rdata, 0, NULL);
1637 
1638 	if (rc == 0)
1639 		cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1640 	cifs_small_buf_release(smb);
1641 	return rc;
1642 }
1643 
1644 int
CIFSSMBRead(const unsigned int xid,struct cifs_io_parms * io_parms,unsigned int * nbytes,char ** buf,int * pbuf_type)1645 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1646 	    unsigned int *nbytes, char **buf, int *pbuf_type)
1647 {
1648 	int rc = -EACCES;
1649 	READ_REQ *pSMB = NULL;
1650 	READ_RSP *pSMBr = NULL;
1651 	char *pReadData = NULL;
1652 	int wct;
1653 	int resp_buf_type = 0;
1654 	struct kvec iov[1];
1655 	struct kvec rsp_iov;
1656 	__u32 pid = io_parms->pid;
1657 	__u16 netfid = io_parms->netfid;
1658 	__u64 offset = io_parms->offset;
1659 	struct cifs_tcon *tcon = io_parms->tcon;
1660 	unsigned int in_len;
1661 	unsigned int count = io_parms->length;
1662 
1663 	cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1664 	if (tcon->ses->capabilities & CAP_LARGE_FILES)
1665 		wct = 12;
1666 	else {
1667 		wct = 10; /* old style read */
1668 		if ((offset >> 32) > 0)  {
1669 			/* can not handle this big offset for old */
1670 			return smb_EIO(smb_eio_trace_read_too_far);
1671 		}
1672 	}
1673 
1674 	*nbytes = 0;
1675 	rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1676 	if (rc < 0)
1677 		return rc;
1678 	in_len = rc;
1679 
1680 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1681 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1682 
1683 	/* tcon and ses pointer are checked in smb_init */
1684 	if (tcon->ses->server == NULL)
1685 		return -ECONNABORTED;
1686 
1687 	pSMB->AndXCommand = 0xFF;       /* none */
1688 	pSMB->Fid = netfid;
1689 	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1690 	if (wct == 12)
1691 		pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1692 
1693 	pSMB->Remaining = 0;
1694 	pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1695 	pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1696 	if (wct == 12)
1697 		pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1698 	else {
1699 		/* old style read */
1700 		struct smb_com_readx_req *pSMBW =
1701 			(struct smb_com_readx_req *)pSMB;
1702 		pSMBW->ByteCount = 0;
1703 	}
1704 
1705 	iov[0].iov_base = (char *)pSMB;
1706 	iov[0].iov_len = in_len;
1707 	rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1708 			  CIFS_LOG_ERROR, &rsp_iov);
1709 	cifs_small_buf_release(pSMB);
1710 	cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1711 	pSMBr = (READ_RSP *)rsp_iov.iov_base;
1712 	if (rc) {
1713 		cifs_dbg(VFS, "Send error in read = %d\n", rc);
1714 	} else {
1715 		int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1716 		data_length = data_length << 16;
1717 		data_length += le16_to_cpu(pSMBr->DataLength);
1718 		*nbytes = data_length;
1719 
1720 		/*check that DataLength would not go beyond end of SMB */
1721 		if ((data_length > CIFSMaxBufSize)
1722 				|| (data_length > count)) {
1723 			cifs_dbg(FYI, "bad length %d for count %d\n",
1724 				 data_length, count);
1725 			rc = smb_EIO2(smb_eio_trace_read_overlarge,
1726 				      data_length, count);
1727 			*nbytes = 0;
1728 		} else {
1729 			pReadData = (char *) (&pSMBr->hdr.Protocol) +
1730 					le16_to_cpu(pSMBr->DataOffset);
1731 /*			if (rc = copy_to_user(buf, pReadData, data_length)) {
1732 				cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1733 				rc = -EFAULT;
1734 			}*/ /* can not use copy_to_user when using page cache*/
1735 			if (*buf)
1736 				memcpy(*buf, pReadData, data_length);
1737 		}
1738 	}
1739 
1740 	if (*buf) {
1741 		free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1742 	} else if (resp_buf_type != CIFS_NO_BUFFER) {
1743 		/* return buffer to caller to free */
1744 		*buf = rsp_iov.iov_base;
1745 		if (resp_buf_type == CIFS_SMALL_BUFFER)
1746 			*pbuf_type = CIFS_SMALL_BUFFER;
1747 		else if (resp_buf_type == CIFS_LARGE_BUFFER)
1748 			*pbuf_type = CIFS_LARGE_BUFFER;
1749 	} /* else no valid buffer on return - leave as null */
1750 
1751 	/* Note: On -EAGAIN error only caller can retry on handle based calls
1752 		since file handle passed in no longer valid */
1753 	return rc;
1754 }
1755 
1756 
1757 int
CIFSSMBWrite(const unsigned int xid,struct cifs_io_parms * io_parms,unsigned int * nbytes,const char * buf)1758 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1759 	     unsigned int *nbytes, const char *buf)
1760 {
1761 	int rc = -EACCES;
1762 	WRITE_REQ *pSMB = NULL;
1763 	WRITE_RSP *pSMBr = NULL;
1764 	int bytes_returned, wct;
1765 	__u32 bytes_sent;
1766 	__u16 byte_count;
1767 	__u32 pid = io_parms->pid;
1768 	__u16 netfid = io_parms->netfid;
1769 	__u64 offset = io_parms->offset;
1770 	struct cifs_tcon *tcon = io_parms->tcon;
1771 	unsigned int count = io_parms->length, in_len;
1772 
1773 	*nbytes = 0;
1774 
1775 	/* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1776 	if (tcon->ses == NULL)
1777 		return -ECONNABORTED;
1778 
1779 	if (tcon->ses->capabilities & CAP_LARGE_FILES)
1780 		wct = 14;
1781 	else {
1782 		wct = 12;
1783 		if ((offset >> 32) > 0) {
1784 			/* can not handle big offset for old srv */
1785 			return smb_EIO(smb_eio_trace_write_too_far);
1786 		}
1787 	}
1788 
1789 	rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1790 		      (void **) &pSMBr);
1791 	if (rc < 0)
1792 		return rc;
1793 	in_len = rc;
1794 
1795 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1796 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1797 
1798 	/* tcon and ses pointer are checked in smb_init */
1799 	if (tcon->ses->server == NULL)
1800 		return -ECONNABORTED;
1801 
1802 	pSMB->AndXCommand = 0xFF;	/* none */
1803 	pSMB->Fid = netfid;
1804 	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1805 	if (wct == 14)
1806 		pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1807 
1808 	pSMB->Reserved = 0xFFFFFFFF;
1809 	pSMB->WriteMode = 0;
1810 	pSMB->Remaining = 0;
1811 
1812 	/* Can increase buffer size if buffer is big enough in some cases ie we
1813 	can send more if LARGE_WRITE_X capability returned by the server and if
1814 	our buffer is big enough or if we convert to iovecs on socket writes
1815 	and eliminate the copy to the CIFS buffer */
1816 	if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1817 		bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1818 	} else {
1819 		bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1820 			 & ~0xFF;
1821 	}
1822 
1823 	if (bytes_sent > count)
1824 		bytes_sent = count;
1825 	pSMB->DataOffset =
1826 		cpu_to_le16(offsetof(struct smb_com_write_req, Data));
1827 	if (buf)
1828 		memcpy(pSMB->Data, buf, bytes_sent);
1829 	else if (count != 0) {
1830 		/* No buffer */
1831 		cifs_buf_release(pSMB);
1832 		return -EINVAL;
1833 	} /* else setting file size with write of zero bytes */
1834 	if (wct == 14)
1835 		byte_count = bytes_sent + 1; /* pad */
1836 	else /* wct == 12 */
1837 		byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1838 
1839 	pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1840 	pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1841 	in_len += byte_count;
1842 
1843 	if (wct == 14)
1844 		pSMB->ByteCount = cpu_to_le16(byte_count);
1845 	else { /* old style write has byte count 4 bytes earlier
1846 		  so 4 bytes pad  */
1847 		struct smb_com_writex_req *pSMBW =
1848 			(struct smb_com_writex_req *)pSMB;
1849 		pSMBW->ByteCount = cpu_to_le16(byte_count);
1850 	}
1851 
1852 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
1853 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1854 	cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1855 	if (rc) {
1856 		cifs_dbg(FYI, "Send error in write = %d\n", rc);
1857 	} else {
1858 		*nbytes = le16_to_cpu(pSMBr->CountHigh);
1859 		*nbytes = (*nbytes) << 16;
1860 		*nbytes += le16_to_cpu(pSMBr->Count);
1861 
1862 		/*
1863 		 * Mask off high 16 bits when bytes written as returned by the
1864 		 * server is greater than bytes requested by the client. Some
1865 		 * OS/2 servers are known to set incorrect CountHigh values.
1866 		 */
1867 		if (*nbytes > count)
1868 			*nbytes &= 0xFFFF;
1869 	}
1870 
1871 	cifs_buf_release(pSMB);
1872 
1873 	/* Note: On -EAGAIN error only caller can retry on handle based calls
1874 		since file handle passed in no longer valid */
1875 
1876 	return rc;
1877 }
1878 
1879 /*
1880  * Check the mid_state and signature on received buffer (if any), and queue the
1881  * workqueue completion task.
1882  */
1883 static void
cifs_writev_callback(struct TCP_Server_Info * server,struct mid_q_entry * mid)1884 cifs_writev_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1885 {
1886 	struct cifs_io_subrequest *wdata = mid->callback_data;
1887 	struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
1888 	WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1889 	struct cifs_credits credits = {
1890 		.value = 1,
1891 		.instance = 0,
1892 		.rreq_debug_id = wdata->rreq->debug_id,
1893 		.rreq_debug_index = wdata->subreq.debug_index,
1894 	};
1895 	ssize_t result;
1896 	size_t written;
1897 
1898 	switch (mid->mid_state) {
1899 	case MID_RESPONSE_RECEIVED:
1900 		result = cifs_check_receive(mid, tcon->ses->server, 0);
1901 		if (result != 0)
1902 			break;
1903 
1904 		written = le16_to_cpu(smb->CountHigh);
1905 		written <<= 16;
1906 		written += le16_to_cpu(smb->Count);
1907 		/*
1908 		 * Mask off high 16 bits when bytes written as returned
1909 		 * by the server is greater than bytes requested by the
1910 		 * client. OS/2 servers are known to set incorrect
1911 		 * CountHigh values.
1912 		 */
1913 		if (written > wdata->subreq.len)
1914 			written &= 0xFFFF;
1915 
1916 		if (written < wdata->subreq.len) {
1917 			result = -ENOSPC;
1918 		} else {
1919 			result = written;
1920 			if (written > 0)
1921 				__set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags);
1922 		}
1923 		break;
1924 	case MID_REQUEST_SUBMITTED:
1925 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_req_submitted);
1926 		__set_bit(NETFS_SREQ_NEED_RETRY, &wdata->subreq.flags);
1927 		result = -EAGAIN;
1928 		break;
1929 	case MID_RETRY_NEEDED:
1930 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_retry_needed);
1931 		__set_bit(NETFS_SREQ_NEED_RETRY, &wdata->subreq.flags);
1932 		result = -EAGAIN;
1933 		break;
1934 	case MID_RESPONSE_MALFORMED:
1935 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed);
1936 		result = smb_EIO(smb_eio_trace_write_rsp_malformed);
1937 		break;
1938 	default:
1939 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown);
1940 		result = smb_EIO1(smb_eio_trace_write_mid_state_unknown,
1941 				  mid->mid_state);
1942 		break;
1943 	}
1944 
1945 	trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index,
1946 			      wdata->credits.value,
1947 			      server->credits, server->in_flight,
1948 			      0, cifs_trace_rw_credits_write_response_clear);
1949 	wdata->credits.value = 0;
1950 	cifs_write_subrequest_terminated(wdata, result);
1951 	release_mid(server, mid);
1952 	trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
1953 			      server->credits, server->in_flight,
1954 			      credits.value, cifs_trace_rw_credits_write_response_add);
1955 	add_credits(tcon->ses->server, &credits, 0);
1956 }
1957 
1958 /* cifs_async_writev - send an async write, and set up mid to handle result */
1959 void
cifs_async_writev(struct cifs_io_subrequest * wdata)1960 cifs_async_writev(struct cifs_io_subrequest *wdata)
1961 {
1962 	int rc = -EACCES;
1963 	WRITE_REQ *req = NULL;
1964 	int wct;
1965 	struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
1966 	struct kvec iov[1];
1967 	struct smb_rqst rqst = { };
1968 	unsigned int in_len;
1969 
1970 	if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1971 		wct = 14;
1972 	} else {
1973 		wct = 12;
1974 		if (wdata->subreq.start >> 32 > 0) {
1975 			/* can not handle big offset for old srv */
1976 			rc = smb_EIO(smb_eio_trace_write_too_far);
1977 			goto out;
1978 		}
1979 	}
1980 
1981 	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&req);
1982 	if (rc < 0)
1983 		goto async_writev_out;
1984 	in_len = rc;
1985 
1986 	req->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid);
1987 	req->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16));
1988 
1989 	req->AndXCommand = 0xFF;	/* none */
1990 	req->Fid = wdata->req->cfile->fid.netfid;
1991 	req->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
1992 	if (wct == 14)
1993 		req->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
1994 	req->Reserved = 0xFFFFFFFF;
1995 	req->WriteMode = 0;
1996 	req->Remaining = 0;
1997 
1998 	req->DataOffset =
1999 	    cpu_to_le16(offsetof(struct smb_com_write_req, Data));
2000 
2001 	iov[0].iov_base = req;
2002 	iov[0].iov_len = in_len + 1; /* +1 for BCC */
2003 
2004 	rqst.rq_iov = iov;
2005 	rqst.rq_nvec = 1;
2006 	rqst.rq_iter = wdata->subreq.io_iter;
2007 
2008 	cifs_dbg(FYI, "async write at %llu %zu bytes\n",
2009 		 wdata->subreq.start, wdata->subreq.len);
2010 
2011 	req->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF);
2012 	req->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
2013 
2014 	if (wct == 14) {
2015 		in_len += wdata->subreq.len + 1;
2016 		put_bcc(wdata->subreq.len + 1, &req->hdr);
2017 	} else {
2018 		/* wct == 12 */
2019 		struct smb_com_writex_req *reqw =
2020 				(struct smb_com_writex_req *)req;
2021 		in_len += wdata->subreq.len + 5;
2022 		put_bcc(wdata->subreq.len + 5, &reqw->hdr);
2023 		iov[0].iov_len += 4; /* pad bigger by four bytes */
2024 	}
2025 
2026 	rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2027 			     cifs_writev_callback, NULL, wdata, 0, NULL);
2028 	/* Can't touch wdata if rc == 0 */
2029 	if (rc == 0)
2030 		cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2031 
2032 async_writev_out:
2033 	cifs_small_buf_release(req);
2034 out:
2035 	if (rc) {
2036 		add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
2037 		cifs_write_subrequest_terminated(wdata, rc);
2038 	}
2039 }
2040 
2041 int
CIFSSMBWrite2(const unsigned int xid,struct cifs_io_parms * io_parms,unsigned int * nbytes,struct kvec * iov,int n_vec)2042 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2043 	      unsigned int *nbytes, struct kvec *iov, int n_vec)
2044 {
2045 	int rc;
2046 	WRITE_REQ *pSMB = NULL;
2047 	int wct;
2048 	int smb_hdr_len;
2049 	int resp_buf_type = 0;
2050 	__u32 pid = io_parms->pid;
2051 	__u16 netfid = io_parms->netfid;
2052 	__u64 offset = io_parms->offset;
2053 	struct cifs_tcon *tcon = io_parms->tcon;
2054 	unsigned int count = io_parms->length;
2055 	struct kvec rsp_iov;
2056 	unsigned int in_len;
2057 
2058 	*nbytes = 0;
2059 
2060 	cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2061 
2062 	if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2063 		wct = 14;
2064 	} else {
2065 		wct = 12;
2066 		if ((offset >> 32) > 0) {
2067 			/* can not handle big offset for old srv */
2068 			return smb_EIO(smb_eio_trace_write_too_far);
2069 		}
2070 	}
2071 	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2072 	if (rc < 0)
2073 		return rc;
2074 	in_len = rc;
2075 
2076 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2077 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2078 
2079 	/* tcon and ses pointer are checked in smb_init */
2080 	if (tcon->ses->server == NULL)
2081 		return -ECONNABORTED;
2082 
2083 	pSMB->AndXCommand = 0xFF;	/* none */
2084 	pSMB->Fid = netfid;
2085 	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2086 	if (wct == 14)
2087 		pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2088 	pSMB->Reserved = 0xFFFFFFFF;
2089 	pSMB->WriteMode = 0;
2090 	pSMB->Remaining = 0;
2091 
2092 	pSMB->DataOffset =
2093 	    cpu_to_le16(offsetof(struct smb_com_write_req, Data));
2094 
2095 	pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2096 	pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2097 	/* header + 1 byte pad */
2098 	smb_hdr_len = in_len + 1;
2099 	if (wct == 14)
2100 		in_len += count + 1;
2101 	else /* wct == 12 */
2102 		in_len += count + 5; /* smb data starts later */
2103 	if (wct == 14)
2104 		pSMB->ByteCount = cpu_to_le16(count + 1);
2105 	else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2106 		struct smb_com_writex_req *pSMBW =
2107 				(struct smb_com_writex_req *)pSMB;
2108 		pSMBW->ByteCount = cpu_to_le16(count + 5);
2109 	}
2110 	iov[0].iov_base = pSMB;
2111 	if (wct == 14)
2112 		iov[0].iov_len = smb_hdr_len + 4;
2113 	else /* wct == 12 pad bigger by four bytes */
2114 		iov[0].iov_len = smb_hdr_len + 8;
2115 
2116 	rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2117 			  &rsp_iov);
2118 	cifs_small_buf_release(pSMB);
2119 	cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2120 	if (rc) {
2121 		cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2122 	} else if (resp_buf_type == 0) {
2123 		/* presumably this can not happen, but best to be safe */
2124 		rc = smb_EIO1(smb_eio_trace_write_bad_buf_type, resp_buf_type);
2125 	} else {
2126 		WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2127 		*nbytes = le16_to_cpu(pSMBr->CountHigh);
2128 		*nbytes = (*nbytes) << 16;
2129 		*nbytes += le16_to_cpu(pSMBr->Count);
2130 
2131 		/*
2132 		 * Mask off high 16 bits when bytes written as returned by the
2133 		 * server is greater than bytes requested by the client. OS/2
2134 		 * servers are known to set incorrect CountHigh values.
2135 		 */
2136 		if (*nbytes > count)
2137 			*nbytes &= 0xFFFF;
2138 	}
2139 
2140 	free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2141 
2142 	/* Note: On -EAGAIN error only caller can retry on handle based calls
2143 		since file handle passed in no longer valid */
2144 
2145 	return rc;
2146 }
2147 
cifs_lockv(const unsigned int xid,struct cifs_tcon * tcon,const __u16 netfid,const __u8 lock_type,const __u32 num_unlock,const __u32 num_lock,LOCKING_ANDX_RANGE * buf)2148 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2149 	       const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2150 	       const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2151 {
2152 	int rc = 0;
2153 	LOCK_REQ *pSMB = NULL;
2154 	struct kvec iov[2];
2155 	struct kvec rsp_iov;
2156 	unsigned int in_len;
2157 	int resp_buf_type;
2158 	__u16 count;
2159 
2160 	cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2161 		 num_lock, num_unlock);
2162 
2163 	rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2164 	if (rc < 0)
2165 		return rc;
2166 	in_len = rc;
2167 
2168 	pSMB->Timeout = 0;
2169 	pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2170 	pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2171 	pSMB->LockType = lock_type;
2172 	pSMB->AndXCommand = 0xFF; /* none */
2173 	pSMB->Fid = netfid; /* netfid stays le */
2174 
2175 	count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2176 	in_len += count;
2177 	pSMB->ByteCount = cpu_to_le16(count);
2178 
2179 	iov[0].iov_base = (char *)pSMB;
2180 	iov[0].iov_len = in_len -
2181 			 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2182 	iov[1].iov_base = (char *)buf;
2183 	iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2184 
2185 	cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2186 	rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2187 			  CIFS_NO_RSP_BUF, &rsp_iov);
2188 	cifs_small_buf_release(pSMB);
2189 	if (rc)
2190 		cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2191 
2192 	return rc;
2193 }
2194 
2195 int
CIFSSMBLock(const unsigned int xid,struct cifs_tcon * tcon,const __u16 smb_file_id,const __u32 netpid,const __u64 len,const __u64 offset,const __u32 numUnlock,const __u32 numLock,const __u8 lockType,const bool waitFlag,const __u8 oplock_level)2196 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2197 	    const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2198 	    const __u64 offset, const __u32 numUnlock,
2199 	    const __u32 numLock, const __u8 lockType,
2200 	    const bool waitFlag, const __u8 oplock_level)
2201 {
2202 	int rc = 0;
2203 	LOCK_REQ *pSMB = NULL;
2204 /*	LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2205 	unsigned int in_len;
2206 	int bytes_returned;
2207 	int flags = CIFS_WINDOWS_LOCK | CIFS_INTERRUPTIBLE_WAIT;
2208 	__u16 count;
2209 
2210 	cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2211 		 (int)waitFlag, numLock);
2212 	rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2213 
2214 	if (rc < 0)
2215 		return rc;
2216 	in_len = rc;
2217 
2218 	if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2219 		/* no response expected */
2220 		flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2221 		pSMB->Timeout = 0;
2222 	} else if (waitFlag) {
2223 		flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2224 		pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2225 	} else {
2226 		pSMB->Timeout = 0;
2227 	}
2228 
2229 	pSMB->NumberOfLocks = cpu_to_le16(numLock);
2230 	pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2231 	pSMB->LockType = lockType;
2232 	pSMB->OplockLevel = oplock_level;
2233 	pSMB->AndXCommand = 0xFF;	/* none */
2234 	pSMB->Fid = smb_file_id; /* netfid stays le */
2235 
2236 	if ((numLock != 0) || (numUnlock != 0)) {
2237 		pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2238 		/* BB where to store pid high? */
2239 		pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2240 		pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2241 		pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2242 		pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2243 		count = sizeof(LOCKING_ANDX_RANGE);
2244 	} else {
2245 		/* oplock break */
2246 		count = 0;
2247 	}
2248 	in_len += count;
2249 	pSMB->ByteCount = cpu_to_le16(count);
2250 
2251 	if (waitFlag)
2252 		rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2253 				 (struct smb_hdr *) pSMB, &bytes_returned,
2254 				 flags);
2255 	else
2256 		rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, in_len, flags);
2257 	cifs_small_buf_release(pSMB);
2258 	cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2259 	if (rc)
2260 		cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2261 
2262 	/* Note: On -EAGAIN error only caller can retry on handle based calls
2263 	since file handle passed in no longer valid */
2264 	return rc;
2265 }
2266 
2267 int
CIFSSMBPosixLock(const unsigned int xid,struct cifs_tcon * tcon,const __u16 smb_file_id,const __u32 netpid,const loff_t start_offset,const __u64 len,struct file_lock * pLockData,const __u16 lock_type,const bool waitFlag)2268 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2269 		const __u16 smb_file_id, const __u32 netpid,
2270 		const loff_t start_offset, const __u64 len,
2271 		struct file_lock *pLockData, const __u16 lock_type,
2272 		const bool waitFlag)
2273 {
2274 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2275 	struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2276 	struct cifs_posix_lock *parm_data;
2277 	unsigned int in_len;
2278 	int rc = 0;
2279 	int sr_flags = CIFS_INTERRUPTIBLE_WAIT;
2280 	int bytes_returned = 0;
2281 	int resp_buf_type = 0;
2282 	__u16 params, param_offset, offset, byte_count, count;
2283 	struct kvec iov[1];
2284 	struct kvec rsp_iov;
2285 
2286 	cifs_dbg(FYI, "Posix Lock\n");
2287 
2288 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2289 	if (rc < 0)
2290 		return rc;
2291 	in_len = rc;
2292 
2293 	pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2294 
2295 	params = 6;
2296 	pSMB->MaxSetupCount = 0;
2297 	pSMB->Reserved = 0;
2298 	pSMB->Flags = 0;
2299 	pSMB->Reserved2 = 0;
2300 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
2301 	offset = param_offset + params;
2302 
2303 	count = sizeof(struct cifs_posix_lock);
2304 	pSMB->MaxParameterCount = cpu_to_le16(2);
2305 	pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2306 	pSMB->SetupCount = 1;
2307 	pSMB->Reserved3 = 0;
2308 	if (pLockData)
2309 		pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2310 	else
2311 		pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2312 	byte_count = 3 /* pad */  + params + count;
2313 	pSMB->DataCount = cpu_to_le16(count);
2314 	pSMB->ParameterCount = cpu_to_le16(params);
2315 	pSMB->TotalDataCount = pSMB->DataCount;
2316 	pSMB->TotalParameterCount = pSMB->ParameterCount;
2317 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
2318 	parm_data = (struct cifs_posix_lock *)(((char *)pSMB) + offset);
2319 
2320 	parm_data->lock_type = cpu_to_le16(lock_type);
2321 	if (waitFlag) {
2322 		sr_flags |= CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2323 		parm_data->lock_flags = cpu_to_le16(1);
2324 		pSMB->Timeout = cpu_to_le32(-1);
2325 	} else
2326 		pSMB->Timeout = 0;
2327 
2328 	parm_data->pid = cpu_to_le32(netpid);
2329 	parm_data->start = cpu_to_le64(start_offset);
2330 	parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2331 
2332 	pSMB->DataOffset = cpu_to_le16(offset);
2333 	pSMB->Fid = smb_file_id;
2334 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2335 	pSMB->Reserved4 = 0;
2336 	in_len += byte_count;
2337 	pSMB->ByteCount = cpu_to_le16(byte_count);
2338 	if (waitFlag) {
2339 		rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2340 				 (struct smb_hdr *) pSMBr, &bytes_returned,
2341 				 sr_flags);
2342 	} else {
2343 		iov[0].iov_base = (char *)pSMB;
2344 		iov[0].iov_len = in_len;
2345 		rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2346 				&resp_buf_type, sr_flags, &rsp_iov);
2347 		pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2348 	}
2349 	cifs_small_buf_release(pSMB);
2350 
2351 	if (rc) {
2352 		cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2353 	} else if (pLockData) {
2354 		/* lock structure can be returned on get */
2355 		__u16 data_offset;
2356 		__u16 data_count;
2357 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2358 
2359 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2360 			rc = smb_EIO2(smb_eio_trace_lock_bcc_too_small,
2361 				      get_bcc(&pSMBr->hdr), sizeof(*parm_data));
2362 			goto plk_err_exit;
2363 		}
2364 		data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2365 		data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2366 		if (data_count < sizeof(struct cifs_posix_lock)) {
2367 			rc = smb_EIO2(smb_eio_trace_lock_data_too_small,
2368 				      data_count, sizeof(struct cifs_posix_lock));
2369 			goto plk_err_exit;
2370 		}
2371 		parm_data = (struct cifs_posix_lock *)
2372 			((char *)&pSMBr->hdr.Protocol + data_offset);
2373 		if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2374 			pLockData->c.flc_type = F_UNLCK;
2375 		else {
2376 			if (parm_data->lock_type ==
2377 					cpu_to_le16(CIFS_RDLCK))
2378 				pLockData->c.flc_type = F_RDLCK;
2379 			else if (parm_data->lock_type ==
2380 					cpu_to_le16(CIFS_WRLCK))
2381 				pLockData->c.flc_type = F_WRLCK;
2382 
2383 			pLockData->fl_start = le64_to_cpu(parm_data->start);
2384 			pLockData->fl_end = pLockData->fl_start +
2385 				(le64_to_cpu(parm_data->length) ?
2386 				 le64_to_cpu(parm_data->length) - 1 : 0);
2387 			pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid);
2388 		}
2389 	}
2390 
2391 plk_err_exit:
2392 	free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2393 
2394 	/* Note: On -EAGAIN error only caller can retry on handle based calls
2395 	   since file handle passed in no longer valid */
2396 
2397 	return rc;
2398 }
2399 
2400 
2401 int
CIFSSMBClose(const unsigned int xid,struct cifs_tcon * tcon,int smb_file_id)2402 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2403 {
2404 	int rc = 0;
2405 	CLOSE_REQ *pSMB = NULL;
2406 	unsigned int in_len;
2407 
2408 	cifs_dbg(FYI, "In CIFSSMBClose\n");
2409 
2410 /* do not retry on dead session on close */
2411 	rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2412 	if (rc == -EAGAIN)
2413 		return 0;
2414 	if (rc < 0)
2415 		return rc;
2416 	in_len = rc;
2417 
2418 	pSMB->FileID = (__u16) smb_file_id;
2419 	pSMB->LastWriteTime = 0xFFFFFFFF;
2420 	pSMB->ByteCount = 0;
2421 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
2422 	cifs_small_buf_release(pSMB);
2423 	cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2424 	if (rc) {
2425 		if (rc != -EINTR) {
2426 			/* EINTR is expected when user ctl-c to kill app */
2427 			cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2428 		}
2429 	}
2430 
2431 	/* Since session is dead, file will be closed on server already */
2432 	if (rc == -EAGAIN)
2433 		rc = 0;
2434 
2435 	return rc;
2436 }
2437 
2438 int
CIFSSMBFlush(const unsigned int xid,struct cifs_tcon * tcon,int smb_file_id)2439 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2440 {
2441 	int rc = 0;
2442 	FLUSH_REQ *pSMB = NULL;
2443 	unsigned int in_len;
2444 
2445 	cifs_dbg(FYI, "In CIFSSMBFlush\n");
2446 
2447 	rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2448 	if (rc < 0)
2449 		return rc;
2450 	in_len = rc;
2451 
2452 	pSMB->FileID = (__u16) smb_file_id;
2453 	pSMB->ByteCount = 0;
2454 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
2455 	cifs_small_buf_release(pSMB);
2456 	cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2457 	if (rc)
2458 		cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2459 
2460 	return rc;
2461 }
2462 
CIFSSMBRename(const unsigned int xid,struct cifs_tcon * tcon,struct dentry * source_dentry,const char * from_name,const char * to_name,struct cifs_sb_info * cifs_sb)2463 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2464 		  struct dentry *source_dentry,
2465 		  const char *from_name, const char *to_name,
2466 		  struct cifs_sb_info *cifs_sb)
2467 {
2468 	int rc = 0;
2469 	RENAME_REQ *pSMB = NULL;
2470 	RENAME_RSP *pSMBr = NULL;
2471 	unsigned int in_len;
2472 	int bytes_returned;
2473 	int name_len, name_len2;
2474 	__u16 count;
2475 	int remap = cifs_remap(cifs_sb);
2476 
2477 	cifs_dbg(FYI, "In CIFSSMBRename\n");
2478 renameRetry:
2479 	rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2480 		      (void **) &pSMBr);
2481 	if (rc < 0)
2482 		return rc;
2483 	in_len = rc;
2484 
2485 	pSMB->BufferFormat = 0x04;
2486 	pSMB->SearchAttributes =
2487 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2488 			ATTR_DIRECTORY);
2489 
2490 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2491 		name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2492 					      from_name, PATH_MAX,
2493 					      cifs_sb->local_nls, remap);
2494 		name_len++;	/* trailing null */
2495 		name_len *= 2;
2496 		pSMB->OldFileName[name_len] = 0x04;	/* pad */
2497 	/* protocol requires ASCII signature byte on Unicode string */
2498 		pSMB->OldFileName[name_len + 1] = 0x00;
2499 		name_len2 =
2500 		    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2501 				       to_name, PATH_MAX, cifs_sb->local_nls,
2502 				       remap);
2503 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2504 		name_len2 *= 2;	/* convert to bytes */
2505 	} else {
2506 		name_len = copy_path_name(pSMB->OldFileName, from_name);
2507 		name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2508 		pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2509 		name_len2++;	/* signature byte */
2510 	}
2511 
2512 	count = 1 /* 1st signature byte */  + name_len + name_len2;
2513 	in_len += count;
2514 	pSMB->ByteCount = cpu_to_le16(count);
2515 
2516 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2517 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2518 	cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2519 	if (rc)
2520 		cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2521 
2522 	cifs_buf_release(pSMB);
2523 
2524 	if (rc == -EAGAIN)
2525 		goto renameRetry;
2526 
2527 	return rc;
2528 }
2529 
CIFSSMBRenameOpenFile(const unsigned int xid,struct cifs_tcon * pTcon,int netfid,const char * target_name,const struct nls_table * nls_codepage,int remap)2530 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2531 		int netfid, const char *target_name,
2532 		const struct nls_table *nls_codepage, int remap)
2533 {
2534 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2535 	struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2536 	struct set_file_rename *rename_info;
2537 	unsigned int in_len;
2538 	char *data_offset;
2539 	char dummy_string[30];
2540 	int rc = 0;
2541 	int bytes_returned = 0;
2542 	int len_of_str;
2543 	__u16 params, param_offset, offset, count, byte_count;
2544 
2545 	cifs_dbg(FYI, "Rename to File by handle\n");
2546 	rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2547 			(void **) &pSMBr);
2548 	if (rc < 0)
2549 		return rc;
2550 	in_len = rc;
2551 
2552 	params = 6;
2553 	pSMB->MaxSetupCount = 0;
2554 	pSMB->Reserved = 0;
2555 	pSMB->Flags = 0;
2556 	pSMB->Timeout = 0;
2557 	pSMB->Reserved2 = 0;
2558 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
2559 	offset = param_offset + params;
2560 
2561 	data_offset = (char *)(pSMB) + offset;
2562 	rename_info = (struct set_file_rename *) data_offset;
2563 	pSMB->MaxParameterCount = cpu_to_le16(2);
2564 	pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2565 	pSMB->SetupCount = 1;
2566 	pSMB->Reserved3 = 0;
2567 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2568 	byte_count = 3 /* pad */  + params;
2569 	pSMB->ParameterCount = cpu_to_le16(params);
2570 	pSMB->TotalParameterCount = pSMB->ParameterCount;
2571 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
2572 	pSMB->DataOffset = cpu_to_le16(offset);
2573 	/* construct random name ".cifs_tmp<inodenum><mid>" */
2574 	rename_info->overwrite = cpu_to_le32(1);
2575 	rename_info->root_fid  = 0;
2576 	/* unicode only call */
2577 	if (target_name == NULL) {
2578 		sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2579 		len_of_str =
2580 			cifsConvertToUTF16((__le16 *)rename_info->target_name,
2581 					dummy_string, 24, nls_codepage, remap);
2582 	} else {
2583 		len_of_str =
2584 			cifsConvertToUTF16((__le16 *)rename_info->target_name,
2585 					target_name, PATH_MAX, nls_codepage,
2586 					remap);
2587 	}
2588 	rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2589 	count = sizeof(struct set_file_rename) + (2 * len_of_str);
2590 	byte_count += count;
2591 	pSMB->DataCount = cpu_to_le16(count);
2592 	pSMB->TotalDataCount = pSMB->DataCount;
2593 	pSMB->Fid = netfid;
2594 	pSMB->InformationLevel =
2595 		cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2596 	pSMB->Reserved4 = 0;
2597 	in_len += byte_count;
2598 	pSMB->ByteCount = cpu_to_le16(byte_count);
2599 	rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, in_len,
2600 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2601 	cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2602 	if (rc)
2603 		cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2604 			 rc);
2605 
2606 	cifs_buf_release(pSMB);
2607 
2608 	/* Note: On -EAGAIN error only caller can retry on handle based calls
2609 		since file handle passed in no longer valid */
2610 
2611 	return rc;
2612 }
2613 
2614 int
CIFSUnixCreateSymLink(const unsigned int xid,struct cifs_tcon * tcon,const char * fromName,const char * toName,const struct nls_table * nls_codepage,int remap)2615 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2616 		      const char *fromName, const char *toName,
2617 		      const struct nls_table *nls_codepage, int remap)
2618 {
2619 	TRANSACTION2_SPI_REQ *pSMB = NULL;
2620 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
2621 	unsigned int in_len;
2622 	char *data_offset;
2623 	int name_len;
2624 	int name_len_target;
2625 	int rc = 0;
2626 	int bytes_returned = 0;
2627 	__u16 params, param_offset, offset, byte_count;
2628 
2629 	cifs_dbg(FYI, "In Symlink Unix style\n");
2630 createSymLinkRetry:
2631 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2632 		      (void **) &pSMBr);
2633 	if (rc < 0)
2634 		return rc;
2635 	in_len = rc;
2636 
2637 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2638 		name_len =
2639 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2640 				/* find define for this maxpathcomponent */
2641 					PATH_MAX, nls_codepage, remap);
2642 		name_len++;	/* trailing null */
2643 		name_len *= 2;
2644 
2645 	} else {
2646 		name_len = copy_path_name(pSMB->FileName, fromName);
2647 	}
2648 	params = 6 + name_len;
2649 	pSMB->MaxSetupCount = 0;
2650 	pSMB->Reserved = 0;
2651 	pSMB->Flags = 0;
2652 	pSMB->Timeout = 0;
2653 	pSMB->Reserved2 = 0;
2654 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
2655 				InformationLevel);
2656 	offset = param_offset + params;
2657 
2658 	data_offset = (char *)pSMB + offset;
2659 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2660 		name_len_target =
2661 		    cifsConvertToUTF16((__le16 *) data_offset, toName,
2662 				/* find define for this maxpathcomponent */
2663 					PATH_MAX, nls_codepage, remap);
2664 		name_len_target++;	/* trailing null */
2665 		name_len_target *= 2;
2666 	} else {
2667 		name_len_target = copy_path_name(data_offset, toName);
2668 	}
2669 
2670 	pSMB->MaxParameterCount = cpu_to_le16(2);
2671 	/* BB find exact max on data count below from sess */
2672 	pSMB->MaxDataCount = cpu_to_le16(1000);
2673 	pSMB->SetupCount = 1;
2674 	pSMB->Reserved3 = 0;
2675 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2676 	byte_count = 3 /* pad */  + params + name_len_target;
2677 	pSMB->DataCount = cpu_to_le16(name_len_target);
2678 	pSMB->ParameterCount = cpu_to_le16(params);
2679 	pSMB->TotalDataCount = pSMB->DataCount;
2680 	pSMB->TotalParameterCount = pSMB->ParameterCount;
2681 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
2682 	pSMB->DataOffset = cpu_to_le16(offset);
2683 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2684 	pSMB->Reserved4 = 0;
2685 	in_len += byte_count;
2686 	pSMB->ByteCount = cpu_to_le16(byte_count);
2687 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2688 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2689 	cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2690 	if (rc)
2691 		cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2692 			 rc);
2693 
2694 	cifs_buf_release(pSMB);
2695 
2696 	if (rc == -EAGAIN)
2697 		goto createSymLinkRetry;
2698 
2699 	return rc;
2700 }
2701 
2702 int
CIFSUnixCreateHardLink(const unsigned int xid,struct cifs_tcon * tcon,const char * fromName,const char * toName,const struct nls_table * nls_codepage,int remap)2703 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2704 		       const char *fromName, const char *toName,
2705 		       const struct nls_table *nls_codepage, int remap)
2706 {
2707 	TRANSACTION2_SPI_REQ *pSMB = NULL;
2708 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
2709 	unsigned int in_len;
2710 	char *data_offset;
2711 	int name_len;
2712 	int name_len_target;
2713 	int rc = 0;
2714 	int bytes_returned = 0;
2715 	__u16 params, param_offset, offset, byte_count;
2716 
2717 	cifs_dbg(FYI, "In Create Hard link Unix style\n");
2718 createHardLinkRetry:
2719 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2720 		      (void **) &pSMBr);
2721 	if (rc < 0)
2722 		return rc;
2723 	in_len = rc;
2724 
2725 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2726 		name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2727 					      PATH_MAX, nls_codepage, remap);
2728 		name_len++;	/* trailing null */
2729 		name_len *= 2;
2730 
2731 	} else {
2732 		name_len = copy_path_name(pSMB->FileName, toName);
2733 	}
2734 	params = 6 + name_len;
2735 	pSMB->MaxSetupCount = 0;
2736 	pSMB->Reserved = 0;
2737 	pSMB->Flags = 0;
2738 	pSMB->Timeout = 0;
2739 	pSMB->Reserved2 = 0;
2740 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
2741 				InformationLevel);
2742 	offset = param_offset + params;
2743 
2744 	data_offset = (char *)pSMB + offset;
2745 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2746 		name_len_target =
2747 		    cifsConvertToUTF16((__le16 *) data_offset, fromName,
2748 				       PATH_MAX, nls_codepage, remap);
2749 		name_len_target++;	/* trailing null */
2750 		name_len_target *= 2;
2751 	} else {
2752 		name_len_target = copy_path_name(data_offset, fromName);
2753 	}
2754 
2755 	pSMB->MaxParameterCount = cpu_to_le16(2);
2756 	/* BB find exact max on data count below from sess*/
2757 	pSMB->MaxDataCount = cpu_to_le16(1000);
2758 	pSMB->SetupCount = 1;
2759 	pSMB->Reserved3 = 0;
2760 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2761 	byte_count = 3 /* pad */  + params + name_len_target;
2762 	pSMB->ParameterCount = cpu_to_le16(params);
2763 	pSMB->TotalParameterCount = pSMB->ParameterCount;
2764 	pSMB->DataCount = cpu_to_le16(name_len_target);
2765 	pSMB->TotalDataCount = pSMB->DataCount;
2766 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
2767 	pSMB->DataOffset = cpu_to_le16(offset);
2768 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2769 	pSMB->Reserved4 = 0;
2770 	in_len += byte_count;
2771 	pSMB->ByteCount = cpu_to_le16(byte_count);
2772 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2773 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2774 	cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2775 	if (rc)
2776 		cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2777 			 rc);
2778 
2779 	cifs_buf_release(pSMB);
2780 	if (rc == -EAGAIN)
2781 		goto createHardLinkRetry;
2782 
2783 	return rc;
2784 }
2785 
CIFSCreateHardLink(const unsigned int xid,struct cifs_tcon * tcon,struct dentry * source_dentry,const char * from_name,const char * to_name,struct cifs_sb_info * cifs_sb)2786 int CIFSCreateHardLink(const unsigned int xid,
2787 		       struct cifs_tcon *tcon,
2788 		       struct dentry *source_dentry,
2789 		       const char *from_name, const char *to_name,
2790 		       struct cifs_sb_info *cifs_sb)
2791 {
2792 	int rc = 0;
2793 	NT_RENAME_REQ *pSMB = NULL;
2794 	RENAME_RSP *pSMBr = NULL;
2795 	unsigned int in_len;
2796 	int bytes_returned;
2797 	int name_len, name_len2;
2798 	__u16 count;
2799 	int remap = cifs_remap(cifs_sb);
2800 
2801 	cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2802 winCreateHardLinkRetry:
2803 
2804 	rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2805 		      (void **) &pSMBr);
2806 	if (rc < 0)
2807 		return rc;
2808 	in_len = rc;
2809 
2810 	pSMB->SearchAttributes =
2811 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2812 			ATTR_DIRECTORY);
2813 	pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2814 	pSMB->ClusterCount = 0;
2815 
2816 	pSMB->BufferFormat = 0x04;
2817 
2818 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2819 		name_len =
2820 		    cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2821 				       PATH_MAX, cifs_sb->local_nls, remap);
2822 		name_len++;	/* trailing null */
2823 		name_len *= 2;
2824 
2825 		/* protocol specifies ASCII buffer format (0x04) for unicode */
2826 		pSMB->OldFileName[name_len] = 0x04;
2827 		pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2828 		name_len2 =
2829 		    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2830 				       to_name, PATH_MAX, cifs_sb->local_nls,
2831 				       remap);
2832 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2833 		name_len2 *= 2;	/* convert to bytes */
2834 	} else {
2835 		name_len = copy_path_name(pSMB->OldFileName, from_name);
2836 		pSMB->OldFileName[name_len] = 0x04;	/* 2nd buffer format */
2837 		name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2838 		name_len2++;	/* signature byte */
2839 	}
2840 
2841 	count = 1 /* string type byte */  + name_len + name_len2;
2842 	in_len += count;
2843 	pSMB->ByteCount = cpu_to_le16(count);
2844 
2845 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2846 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2847 	cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2848 	if (rc)
2849 		cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2850 
2851 	cifs_buf_release(pSMB);
2852 	if (rc == -EAGAIN)
2853 		goto winCreateHardLinkRetry;
2854 
2855 	return rc;
2856 }
2857 
2858 int
CIFSSMBUnixQuerySymLink(const unsigned int xid,struct cifs_tcon * tcon,const unsigned char * searchName,char ** symlinkinfo,const struct nls_table * nls_codepage,int remap)2859 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2860 			const unsigned char *searchName, char **symlinkinfo,
2861 			const struct nls_table *nls_codepage, int remap)
2862 {
2863 /* SMB_QUERY_FILE_UNIX_LINK */
2864 	TRANSACTION2_QPI_REQ *pSMB = NULL;
2865 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
2866 	unsigned int in_len;
2867 	int rc = 0;
2868 	int bytes_returned;
2869 	int name_len;
2870 	__u16 params, byte_count;
2871 	char *data_start;
2872 
2873 	cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2874 
2875 querySymLinkRetry:
2876 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2877 		      (void **) &pSMBr);
2878 	if (rc < 0)
2879 		return rc;
2880 	in_len = rc;
2881 
2882 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2883 		name_len =
2884 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
2885 					   searchName, PATH_MAX, nls_codepage,
2886 					   remap);
2887 		name_len++;	/* trailing null */
2888 		name_len *= 2;
2889 	} else {
2890 		name_len = copy_path_name(pSMB->FileName, searchName);
2891 	}
2892 
2893 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
2894 	pSMB->TotalDataCount = 0;
2895 	pSMB->MaxParameterCount = cpu_to_le16(2);
2896 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2897 	pSMB->MaxSetupCount = 0;
2898 	pSMB->Reserved = 0;
2899 	pSMB->Flags = 0;
2900 	pSMB->Timeout = 0;
2901 	pSMB->Reserved2 = 0;
2902 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
2903 		struct smb_com_transaction2_qpi_req, InformationLevel));
2904 	pSMB->DataCount = 0;
2905 	pSMB->DataOffset = 0;
2906 	pSMB->SetupCount = 1;
2907 	pSMB->Reserved3 = 0;
2908 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2909 	byte_count = params + 1 /* pad */ ;
2910 	pSMB->TotalParameterCount = cpu_to_le16(params);
2911 	pSMB->ParameterCount = pSMB->TotalParameterCount;
2912 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2913 	pSMB->Reserved4 = 0;
2914 	in_len += byte_count;
2915 	pSMB->ByteCount = cpu_to_le16(byte_count);
2916 
2917 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2918 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2919 	if (rc) {
2920 		cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2921 	} else {
2922 		/* decode response */
2923 
2924 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2925 		/* BB also check enough total bytes returned */
2926 		if (rc || get_bcc(&pSMBr->hdr) < 2)
2927 			rc = smb_EIO2(smb_eio_trace_qsym_bcc_too_small,
2928 				      get_bcc(&pSMBr->hdr), 2);
2929 		else {
2930 			bool is_unicode;
2931 			u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2932 
2933 			data_start = ((char *) &pSMBr->hdr.Protocol) +
2934 					   le16_to_cpu(pSMBr->t2.DataOffset);
2935 
2936 			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2937 				is_unicode = true;
2938 			else
2939 				is_unicode = false;
2940 
2941 			/* BB FIXME investigate remapping reserved chars here */
2942 			*symlinkinfo = cifs_strndup_from_utf16(data_start,
2943 					count, is_unicode, nls_codepage);
2944 			if (!*symlinkinfo)
2945 				rc = -ENOMEM;
2946 		}
2947 	}
2948 	cifs_buf_release(pSMB);
2949 	if (rc == -EAGAIN)
2950 		goto querySymLinkRetry;
2951 	return rc;
2952 }
2953 
cifs_query_reparse_point(const unsigned int xid,struct cifs_tcon * tcon,struct cifs_sb_info * cifs_sb,const char * full_path,u32 * tag,struct kvec * rsp,int * rsp_buftype)2954 int cifs_query_reparse_point(const unsigned int xid,
2955 			     struct cifs_tcon *tcon,
2956 			     struct cifs_sb_info *cifs_sb,
2957 			     const char *full_path,
2958 			     u32 *tag, struct kvec *rsp,
2959 			     int *rsp_buftype)
2960 {
2961 	struct reparse_data_buffer *buf;
2962 	struct cifs_open_parms oparms;
2963 	TRANSACT_IOCTL_REQ *io_req = NULL;
2964 	TRANSACT_IOCTL_RSP *io_rsp = NULL;
2965 	struct cifs_fid fid;
2966 	unsigned int in_len;
2967 	__u32 data_offset, data_count, len;
2968 	__u8 *start, *end;
2969 	int io_rsp_len;
2970 	int oplock = 0;
2971 	int rc;
2972 
2973 	cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
2974 
2975 	if (cap_unix(tcon->ses))
2976 		return -EOPNOTSUPP;
2977 
2978 	if (!CIFS_REPARSE_SUPPORT(tcon))
2979 		return -EOPNOTSUPP;
2980 
2981 	oparms = (struct cifs_open_parms) {
2982 		.tcon = tcon,
2983 		.cifs_sb = cifs_sb,
2984 		.desired_access = FILE_READ_ATTRIBUTES,
2985 		.create_options = cifs_create_options(cifs_sb,
2986 						      OPEN_REPARSE_POINT),
2987 		.disposition = FILE_OPEN,
2988 		.path = full_path,
2989 		.fid = &fid,
2990 	};
2991 
2992 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
2993 	if (rc)
2994 		return rc;
2995 
2996 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
2997 		      (void **)&io_req, (void **)&io_rsp);
2998 	if (rc < 0)
2999 		goto error;
3000 	in_len = rc;
3001 
3002 	io_req->TotalParameterCount = 0;
3003 	io_req->TotalDataCount = 0;
3004 	io_req->MaxParameterCount = cpu_to_le32(0);
3005 	/* BB find exact data count max from sess structure BB */
3006 	io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3007 	io_req->MaxSetupCount = 1;
3008 	io_req->Reserved = 0;
3009 	io_req->ParameterOffset = 0;
3010 	io_req->DataCount = 0;
3011 	io_req->DataOffset = 0;
3012 	io_req->SetupCount = 4;
3013 	io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3014 	io_req->ParameterCount = io_req->TotalParameterCount;
3015 	io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3016 	io_req->IsFsctl = 1;
3017 	io_req->IsRootFlag = 0;
3018 	io_req->Fid = fid.netfid;
3019 	io_req->ByteCount = 0;
3020 
3021 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, in_len,
3022 			 (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
3023 	if (rc)
3024 		goto error;
3025 
3026 	data_offset = le32_to_cpu(io_rsp->DataOffset);
3027 	data_count = le32_to_cpu(io_rsp->DataCount);
3028 	if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
3029 	    !data_count || data_count > 2048) {
3030 		rc = smb_EIO2(smb_eio_trace_qreparse_sizes_wrong,
3031 			      get_bcc(&io_rsp->hdr), data_count);
3032 		goto error;
3033 	}
3034 
3035 	/* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */
3036 	if (io_rsp->SetupCount != 1) {
3037 		rc = smb_EIO2(smb_eio_trace_qreparse_setup_count,
3038 			      io_rsp->SetupCount, 1);
3039 		goto error;
3040 	}
3041 
3042 	/*
3043 	 * ReturnedDataLen is output length of executed IOCTL.
3044 	 * DataCount is output length transferred over network.
3045 	 * Check that we have full FSCTL_GET_REPARSE_POINT buffer.
3046 	 */
3047 	if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) {
3048 		rc = smb_EIO2(smb_eio_trace_qreparse_ret_datalen,
3049 			      data_count, le16_to_cpu(io_rsp->ReturnedDataLen));
3050 		goto error;
3051 	}
3052 
3053 	end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
3054 	start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
3055 	if (start >= end) {
3056 		rc = smb_EIO2(smb_eio_trace_qreparse_data_area,
3057 			      (unsigned long)start - (unsigned long)io_rsp,
3058 			      (unsigned long)end - (unsigned long)io_rsp);
3059 		goto error;
3060 	}
3061 
3062 	data_count = le16_to_cpu(io_rsp->ByteCount);
3063 	buf = (struct reparse_data_buffer *)start;
3064 	len = sizeof(*buf);
3065 	if (data_count < len ||
3066 	    data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
3067 		rc = smb_EIO2(smb_eio_trace_qreparse_rep_datalen,
3068 			      data_count, le16_to_cpu(buf->ReparseDataLength) + len);
3069 		goto error;
3070 	}
3071 
3072 	*tag = le32_to_cpu(buf->ReparseTag);
3073 	rsp->iov_base = io_rsp;
3074 	rsp->iov_len = io_rsp_len;
3075 	*rsp_buftype = CIFS_LARGE_BUFFER;
3076 	CIFSSMBClose(xid, tcon, fid.netfid);
3077 	return 0;
3078 
3079 error:
3080 	cifs_buf_release(io_req);
3081 	CIFSSMBClose(xid, tcon, fid.netfid);
3082 	return rc;
3083 }
3084 
cifs_create_reparse_inode(struct cifs_open_info_data * data,struct super_block * sb,const unsigned int xid,struct cifs_tcon * tcon,const char * full_path,bool directory,struct kvec * reparse_iov,struct kvec * xattr_iov)3085 struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
3086 					struct super_block *sb,
3087 					const unsigned int xid,
3088 					struct cifs_tcon *tcon,
3089 					const char *full_path,
3090 					bool directory,
3091 					struct kvec *reparse_iov,
3092 					struct kvec *xattr_iov)
3093 {
3094 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
3095 	struct cifs_open_parms oparms;
3096 	TRANSACT_IOCTL_REQ *io_req;
3097 	struct inode *new = NULL;
3098 	struct kvec in_iov[2];
3099 	struct kvec out_iov;
3100 	struct cifs_fid fid;
3101 	unsigned int in_len;
3102 	int oplock = 0;
3103 	int buf_type = 0;
3104 	int rc;
3105 
3106 	cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
3107 
3108 	/*
3109 	 * If server filesystem does not support reparse points then do not
3110 	 * attempt to create reparse point. This will prevent creating unusable
3111 	 * empty object on the server.
3112 	 */
3113 	if (!CIFS_REPARSE_SUPPORT(tcon))
3114 		return ERR_PTR(-EOPNOTSUPP);
3115 
3116 #ifndef CONFIG_CIFS_XATTR
3117 	if (xattr_iov)
3118 		return ERR_PTR(-EOPNOTSUPP);
3119 #endif
3120 
3121 	oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
3122 			     FILE_READ_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA,
3123 			     FILE_CREATE,
3124 			     (directory ? CREATE_NOT_FILE : CREATE_NOT_DIR) | OPEN_REPARSE_POINT,
3125 			     ACL_NO_MODE);
3126 	oparms.fid = &fid;
3127 
3128 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
3129 	if (rc)
3130 		return ERR_PTR(rc);
3131 
3132 #ifdef CONFIG_CIFS_XATTR
3133 	if (xattr_iov) {
3134 		struct smb2_file_full_ea_info *ea;
3135 
3136 		ea = &((struct smb2_create_ea_ctx *)xattr_iov->iov_base)->ea;
3137 		while (1) {
3138 			rc = CIFSSMBSetEA(xid,
3139 					  tcon,
3140 					  full_path,
3141 					  &ea->ea_data[0],
3142 					  &ea->ea_data[ea->ea_name_length+1],
3143 					  le16_to_cpu(ea->ea_value_length),
3144 					  cifs_sb->local_nls,
3145 					  cifs_sb);
3146 			if (rc)
3147 				goto out_close;
3148 			if (le32_to_cpu(ea->next_entry_offset) == 0)
3149 				break;
3150 			ea = (struct smb2_file_full_ea_info *)((u8 *)ea +
3151 				le32_to_cpu(ea->next_entry_offset));
3152 		}
3153 	}
3154 #endif
3155 
3156 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, NULL);
3157 	if (rc < 0)
3158 		goto out_close;
3159 	in_len = rc;
3160 	in_len += sizeof(io_req->Pad);
3161 
3162 	/* NT IOCTL response contains one-word long output setup buffer with size of output data. */
3163 	io_req->MaxSetupCount = 1;
3164 	/* NT IOCTL response does not contain output parameters. */
3165 	io_req->MaxParameterCount = cpu_to_le32(0);
3166 	/* FSCTL_SET_REPARSE_POINT response contains empty output data. */
3167 	io_req->MaxDataCount = cpu_to_le32(0);
3168 
3169 	io_req->TotalParameterCount = cpu_to_le32(0);
3170 	io_req->TotalDataCount = cpu_to_le32(reparse_iov->iov_len);
3171 	io_req->ParameterCount = io_req->TotalParameterCount;
3172 	io_req->ParameterOffset = cpu_to_le32(0);
3173 	io_req->DataCount = io_req->TotalDataCount;
3174 	io_req->DataOffset = cpu_to_le32(offsetof(typeof(*io_req), Data));
3175 	io_req->SetupCount = 4;
3176 	io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3177 	io_req->FunctionCode = cpu_to_le32(FSCTL_SET_REPARSE_POINT);
3178 	io_req->Fid = fid.netfid;
3179 	io_req->IsFsctl = 1;
3180 	io_req->IsRootFlag = 0;
3181 	io_req->ByteCount = cpu_to_le16(le32_to_cpu(io_req->DataCount) + sizeof(io_req->Pad));
3182 
3183 	in_iov[0].iov_base = (char *)io_req;
3184 	in_iov[0].iov_len = in_len;
3185 	in_iov[1] = *reparse_iov;
3186 	rc = SendReceive2(xid, tcon->ses, in_iov, ARRAY_SIZE(in_iov), &buf_type,
3187 			  CIFS_NO_RSP_BUF, &out_iov);
3188 
3189 	cifs_buf_release(io_req);
3190 
3191 	if (!rc)
3192 		rc = cifs_get_inode_info(&new, full_path, data, sb, xid, NULL);
3193 
3194 out_close:
3195 	CIFSSMBClose(xid, tcon, fid.netfid);
3196 
3197 	/*
3198 	 * If CREATE was successful but FSCTL_SET_REPARSE_POINT failed then
3199 	 * remove the intermediate object created by CREATE. Otherwise
3200 	 * empty object stay on the server when reparse call failed.
3201 	 */
3202 	if (rc)
3203 		CIFSSMBDelFile(xid, tcon, full_path, cifs_sb, NULL);
3204 
3205 	return rc ? ERR_PTR(rc) : new;
3206 }
3207 
3208 int
CIFSSMB_set_compression(const unsigned int xid,struct cifs_tcon * tcon,__u16 fid)3209 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3210 		    __u16 fid)
3211 {
3212 	int rc = 0;
3213 	int bytes_returned;
3214 	struct smb_com_transaction_compr_ioctl_req *pSMB;
3215 	struct smb_com_transaction_ioctl_rsp *pSMBr;
3216 	unsigned int in_len;
3217 
3218 	cifs_dbg(FYI, "Set compression for %u\n", fid);
3219 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3220 		      (void **) &pSMBr);
3221 	if (rc < 0)
3222 		return rc;
3223 	in_len = rc;
3224 
3225 	pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3226 
3227 	pSMB->TotalParameterCount = 0;
3228 	pSMB->TotalDataCount = cpu_to_le32(2);
3229 	pSMB->MaxParameterCount = 0;
3230 	pSMB->MaxDataCount = 0;
3231 	pSMB->MaxSetupCount = 4;
3232 	pSMB->Reserved = 0;
3233 	pSMB->ParameterOffset = 0;
3234 	pSMB->DataCount = cpu_to_le32(2);
3235 	pSMB->DataOffset =
3236 		cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3237 				     compression_state));  /* 84 */
3238 	pSMB->SetupCount = 4;
3239 	pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3240 	pSMB->ParameterCount = 0;
3241 	pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3242 	pSMB->IsFsctl = 1; /* FSCTL */
3243 	pSMB->IsRootFlag = 0;
3244 	pSMB->Fid = fid; /* file handle always le */
3245 	/* 3 byte pad, followed by 2 byte compress state */
3246 	pSMB->ByteCount = cpu_to_le16(5);
3247 	in_len += 5;
3248 
3249 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3250 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3251 	if (rc)
3252 		cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3253 
3254 	cifs_buf_release(pSMB);
3255 
3256 	/*
3257 	 * Note: On -EAGAIN error only caller can retry on handle based calls
3258 	 * since file handle passed in no longer valid.
3259 	 */
3260 	return rc;
3261 }
3262 
3263 
3264 #ifdef CONFIG_CIFS_POSIX
3265 
3266 #ifdef CONFIG_FS_POSIX_ACL
3267 /**
3268  * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
3269  * @ace: POSIX ACL entry to store converted ACL into
3270  * @cifs_ace: ACL in cifs format
3271  *
3272  * Convert an Access Control Entry from wire format to local POSIX xattr
3273  * format.
3274  *
3275  * Note that the @cifs_uid member is used to store both {g,u}id_t.
3276  */
cifs_init_posix_acl(struct posix_acl_entry * ace,struct cifs_posix_ace * cifs_ace)3277 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
3278 				struct cifs_posix_ace *cifs_ace)
3279 {
3280 	/* u8 cifs fields do not need le conversion */
3281 	ace->e_perm = cifs_ace->cifs_e_perm;
3282 	ace->e_tag = cifs_ace->cifs_e_tag;
3283 
3284 	switch (ace->e_tag) {
3285 	case ACL_USER:
3286 		ace->e_uid = make_kuid(&init_user_ns,
3287 				       le64_to_cpu(cifs_ace->cifs_uid));
3288 		break;
3289 	case ACL_GROUP:
3290 		ace->e_gid = make_kgid(&init_user_ns,
3291 				       le64_to_cpu(cifs_ace->cifs_uid));
3292 		break;
3293 	}
3294 	return;
3295 }
3296 
3297 /**
3298  * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
3299  * @acl: ACLs returned in POSIX ACL format
3300  * @src: ACLs in cifs format
3301  * @acl_type: type of POSIX ACL requested
3302  * @size_of_data_area: size of SMB we got
3303  *
3304  * This function converts ACLs from cifs format to POSIX ACL format.
3305  * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
3306  * their uapi format is returned.
3307  */
cifs_to_posix_acl(struct posix_acl ** acl,char * src,const int acl_type,const int size_of_data_area)3308 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
3309 			     const int acl_type, const int size_of_data_area)
3310 {
3311 	int size =  0;
3312 	__u16 count;
3313 	struct cifs_posix_ace *pACE;
3314 	struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3315 	struct posix_acl *kacl = NULL;
3316 	struct posix_acl_entry *pa, *pe;
3317 
3318 	if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3319 		return -EOPNOTSUPP;
3320 
3321 	if (acl_type == ACL_TYPE_ACCESS) {
3322 		count = le16_to_cpu(cifs_acl->access_entry_count);
3323 		pACE = &cifs_acl->ace_array[0];
3324 		size = sizeof(struct cifs_posix_acl);
3325 		size += sizeof(struct cifs_posix_ace) * count;
3326 		/* check if we would go beyond end of SMB */
3327 		if (size_of_data_area < size) {
3328 			cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3329 				 size_of_data_area, size);
3330 			return -EINVAL;
3331 		}
3332 	} else if (acl_type == ACL_TYPE_DEFAULT) {
3333 		count = le16_to_cpu(cifs_acl->access_entry_count);
3334 		size = sizeof(struct cifs_posix_acl);
3335 		size += sizeof(struct cifs_posix_ace) * count;
3336 		/* skip past access ACEs to get to default ACEs */
3337 		pACE = &cifs_acl->ace_array[count];
3338 		count = le16_to_cpu(cifs_acl->default_entry_count);
3339 		size += sizeof(struct cifs_posix_ace) * count;
3340 		/* check if we would go beyond end of SMB */
3341 		if (size_of_data_area < size)
3342 			return -EINVAL;
3343 	} else {
3344 		/* illegal type */
3345 		return -EINVAL;
3346 	}
3347 
3348 	/* Allocate number of POSIX ACLs to store in VFS format. */
3349 	kacl = posix_acl_alloc(count, GFP_NOFS);
3350 	if (!kacl)
3351 		return -ENOMEM;
3352 
3353 	FOREACH_ACL_ENTRY(pa, kacl, pe) {
3354 		cifs_init_posix_acl(pa, pACE);
3355 		pACE++;
3356 	}
3357 
3358 	*acl = kacl;
3359 	return 0;
3360 }
3361 
3362 /**
3363  * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
3364  * @cifs_ace: the cifs ACL entry to store into
3365  * @local_ace: the POSIX ACL entry to convert
3366  */
cifs_init_ace(struct cifs_posix_ace * cifs_ace,const struct posix_acl_entry * local_ace)3367 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
3368 			  const struct posix_acl_entry *local_ace)
3369 {
3370 	cifs_ace->cifs_e_perm = local_ace->e_perm;
3371 	cifs_ace->cifs_e_tag =  local_ace->e_tag;
3372 
3373 	switch (local_ace->e_tag) {
3374 	case ACL_USER:
3375 		cifs_ace->cifs_uid =
3376 			cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
3377 		break;
3378 	case ACL_GROUP:
3379 		cifs_ace->cifs_uid =
3380 			cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
3381 		break;
3382 	default:
3383 		cifs_ace->cifs_uid = cpu_to_le64(-1);
3384 	}
3385 }
3386 
3387 /**
3388  * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
3389  * @parm_data: ACLs in cifs format to convert to
3390  * @acl: ACLs in POSIX ACL format to convert from
3391  * @acl_type: the type of POSIX ACLs stored in @acl
3392  *
3393  * Return: the number cifs ACL entries after conversion
3394  */
posix_acl_to_cifs(char * parm_data,const struct posix_acl * acl,const int acl_type)3395 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
3396 			       const int acl_type)
3397 {
3398 	__u16 rc = 0;
3399 	struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3400 	const struct posix_acl_entry *pa, *pe;
3401 	int count;
3402 	int i = 0;
3403 
3404 	if ((acl == NULL) || (cifs_acl == NULL))
3405 		return 0;
3406 
3407 	count = acl->a_count;
3408 	cifs_dbg(FYI, "setting acl with %d entries\n", count);
3409 
3410 	/*
3411 	 * Note that the uapi POSIX ACL version is verified by the VFS and is
3412 	 * independent of the cifs ACL version. Changing the POSIX ACL version
3413 	 * is a uapi change and if it's changed we will pass down the POSIX ACL
3414 	 * version in struct posix_acl from the VFS. For now there's really
3415 	 * only one that all filesystems know how to deal with.
3416 	 */
3417 	cifs_acl->version = cpu_to_le16(1);
3418 	if (acl_type == ACL_TYPE_ACCESS) {
3419 		cifs_acl->access_entry_count = cpu_to_le16(count);
3420 		cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3421 	} else if (acl_type == ACL_TYPE_DEFAULT) {
3422 		cifs_acl->default_entry_count = cpu_to_le16(count);
3423 		cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3424 	} else {
3425 		cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3426 		return 0;
3427 	}
3428 	FOREACH_ACL_ENTRY(pa, acl, pe) {
3429 		cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3430 	}
3431 	if (rc == 0) {
3432 		rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3433 		rc += sizeof(struct cifs_posix_acl);
3434 		/* BB add check to make sure ACL does not overflow SMB */
3435 	}
3436 	return rc;
3437 }
3438 
cifs_do_get_acl(const unsigned int xid,struct cifs_tcon * tcon,const unsigned char * searchName,struct posix_acl ** acl,const int acl_type,const struct nls_table * nls_codepage,int remap)3439 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3440 		    const unsigned char *searchName, struct posix_acl **acl,
3441 		    const int acl_type, const struct nls_table *nls_codepage,
3442 		    int remap)
3443 {
3444 /* SMB_QUERY_POSIX_ACL */
3445 	TRANSACTION2_QPI_REQ *pSMB = NULL;
3446 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
3447 	unsigned int in_len;
3448 	int rc = 0;
3449 	int bytes_returned;
3450 	int name_len;
3451 	__u16 params, byte_count;
3452 
3453 	cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3454 
3455 queryAclRetry:
3456 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3457 		(void **) &pSMBr);
3458 	if (rc < 0)
3459 		return rc;
3460 	in_len = rc;
3461 
3462 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3463 		name_len =
3464 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
3465 					   searchName, PATH_MAX, nls_codepage,
3466 					   remap);
3467 		name_len++;     /* trailing null */
3468 		name_len *= 2;
3469 		pSMB->FileName[name_len] = 0;
3470 		pSMB->FileName[name_len+1] = 0;
3471 	} else {
3472 		name_len = copy_path_name(pSMB->FileName, searchName);
3473 	}
3474 
3475 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3476 	pSMB->TotalDataCount = 0;
3477 	pSMB->MaxParameterCount = cpu_to_le16(2);
3478 	/* BB find exact max data count below from sess structure BB */
3479 	pSMB->MaxDataCount = cpu_to_le16(4000);
3480 	pSMB->MaxSetupCount = 0;
3481 	pSMB->Reserved = 0;
3482 	pSMB->Flags = 0;
3483 	pSMB->Timeout = 0;
3484 	pSMB->Reserved2 = 0;
3485 	pSMB->ParameterOffset = cpu_to_le16(
3486 		offsetof(struct smb_com_transaction2_qpi_req,
3487 			 InformationLevel));
3488 	pSMB->DataCount = 0;
3489 	pSMB->DataOffset = 0;
3490 	pSMB->SetupCount = 1;
3491 	pSMB->Reserved3 = 0;
3492 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3493 	byte_count = params + 1 /* pad */ ;
3494 	pSMB->TotalParameterCount = cpu_to_le16(params);
3495 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3496 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3497 	pSMB->Reserved4 = 0;
3498 	in_len += byte_count;
3499 	pSMB->ByteCount = cpu_to_le16(byte_count);
3500 
3501 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3502 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
3503 	cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3504 	if (rc) {
3505 		cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3506 	} else {
3507 		/* decode response */
3508 
3509 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3510 		/* BB also check enough total bytes returned */
3511 		if (rc || get_bcc(&pSMBr->hdr) < 2)
3512 			rc = smb_EIO2(smb_eio_trace_getacl_bcc_too_small,
3513 				      get_bcc(&pSMBr->hdr), 2);
3514 		else {
3515 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3516 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3517 			rc = cifs_to_posix_acl(acl,
3518 				(char *)&pSMBr->hdr.Protocol+data_offset,
3519 				acl_type, count);
3520 		}
3521 	}
3522 	cifs_buf_release(pSMB);
3523 	/*
3524 	 * The else branch after SendReceive() doesn't return EAGAIN so if we
3525 	 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3526 	 * here and don't leak POSIX ACLs.
3527 	 */
3528 	if (rc == -EAGAIN)
3529 		goto queryAclRetry;
3530 	return rc;
3531 }
3532 
cifs_do_set_acl(const unsigned int xid,struct cifs_tcon * tcon,const unsigned char * fileName,const struct posix_acl * acl,const int acl_type,const struct nls_table * nls_codepage,int remap)3533 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3534 		    const unsigned char *fileName, const struct posix_acl *acl,
3535 		    const int acl_type, const struct nls_table *nls_codepage,
3536 		    int remap)
3537 {
3538 	struct smb_com_transaction2_spi_req *pSMB = NULL;
3539 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3540 	unsigned int in_len;
3541 	char *parm_data;
3542 	int name_len;
3543 	int rc = 0;
3544 	int bytes_returned = 0;
3545 	__u16 params, byte_count, data_count, param_offset, offset;
3546 
3547 	cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3548 setAclRetry:
3549 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3550 		      (void **) &pSMBr);
3551 	if (rc < 0)
3552 		return rc;
3553 	in_len = rc;
3554 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3555 		name_len =
3556 			cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3557 					   PATH_MAX, nls_codepage, remap);
3558 		name_len++;     /* trailing null */
3559 		name_len *= 2;
3560 	} else {
3561 		name_len = copy_path_name(pSMB->FileName, fileName);
3562 	}
3563 	params = 6 + name_len;
3564 	pSMB->MaxParameterCount = cpu_to_le16(2);
3565 	/* BB find max SMB size from sess */
3566 	pSMB->MaxDataCount = cpu_to_le16(1000);
3567 	pSMB->MaxSetupCount = 0;
3568 	pSMB->Reserved = 0;
3569 	pSMB->Flags = 0;
3570 	pSMB->Timeout = 0;
3571 	pSMB->Reserved2 = 0;
3572 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
3573 				InformationLevel);
3574 	offset = param_offset + params;
3575 	parm_data = ((char *)pSMB) + offset;
3576 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
3577 
3578 	/* convert to on the wire format for POSIX ACL */
3579 	data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3580 
3581 	if (data_count == 0) {
3582 		rc = -EOPNOTSUPP;
3583 		goto setACLerrorExit;
3584 	}
3585 	pSMB->DataOffset = cpu_to_le16(offset);
3586 	pSMB->SetupCount = 1;
3587 	pSMB->Reserved3 = 0;
3588 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3589 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3590 	byte_count = 3 /* pad */  + params + data_count;
3591 	pSMB->DataCount = cpu_to_le16(data_count);
3592 	pSMB->TotalDataCount = pSMB->DataCount;
3593 	pSMB->ParameterCount = cpu_to_le16(params);
3594 	pSMB->TotalParameterCount = pSMB->ParameterCount;
3595 	pSMB->Reserved4 = 0;
3596 	in_len += byte_count;
3597 	pSMB->ByteCount = cpu_to_le16(byte_count);
3598 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3599 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3600 	if (rc)
3601 		cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3602 
3603 setACLerrorExit:
3604 	cifs_buf_release(pSMB);
3605 	if (rc == -EAGAIN)
3606 		goto setAclRetry;
3607 	return rc;
3608 }
3609 #else
cifs_do_get_acl(const unsigned int xid,struct cifs_tcon * tcon,const unsigned char * searchName,struct posix_acl ** acl,const int acl_type,const struct nls_table * nls_codepage,int remap)3610 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3611 		    const unsigned char *searchName, struct posix_acl **acl,
3612 		    const int acl_type, const struct nls_table *nls_codepage,
3613 		    int remap)
3614 {
3615 	return -EOPNOTSUPP;
3616 }
3617 
cifs_do_set_acl(const unsigned int xid,struct cifs_tcon * tcon,const unsigned char * fileName,const struct posix_acl * acl,const int acl_type,const struct nls_table * nls_codepage,int remap)3618 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3619 		    const unsigned char *fileName, const struct posix_acl *acl,
3620 		    const int acl_type, const struct nls_table *nls_codepage,
3621 		    int remap)
3622 {
3623 	return -EOPNOTSUPP;
3624 }
3625 #endif /* CONFIG_FS_POSIX_ACL */
3626 
3627 int
CIFSGetExtAttr(const unsigned int xid,struct cifs_tcon * tcon,const int netfid,__u64 * pExtAttrBits,__u64 * pMask)3628 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3629 	       const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3630 {
3631 	int rc = 0;
3632 	struct smb_t2_qfi_req *pSMB = NULL;
3633 	struct smb_t2_qfi_rsp *pSMBr = NULL;
3634 	unsigned int in_len;
3635 	int bytes_returned;
3636 	__u16 params, byte_count;
3637 
3638 	cifs_dbg(FYI, "In GetExtAttr\n");
3639 	if (tcon == NULL)
3640 		return -ENODEV;
3641 
3642 GetExtAttrRetry:
3643 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3644 		      (void **) &pSMBr);
3645 	if (rc < 0)
3646 		return rc;
3647 	in_len = rc;
3648 
3649 	params = 2 /* level */ + 2 /* fid */;
3650 	pSMB->t2.TotalDataCount = 0;
3651 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3652 	/* BB find exact max data count below from sess structure BB */
3653 	pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3654 	pSMB->t2.MaxSetupCount = 0;
3655 	pSMB->t2.Reserved = 0;
3656 	pSMB->t2.Flags = 0;
3657 	pSMB->t2.Timeout = 0;
3658 	pSMB->t2.Reserved2 = 0;
3659 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3660 					       Fid));
3661 	pSMB->t2.DataCount = 0;
3662 	pSMB->t2.DataOffset = 0;
3663 	pSMB->t2.SetupCount = 1;
3664 	pSMB->t2.Reserved3 = 0;
3665 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3666 	byte_count = params + 1 /* pad */ ;
3667 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3668 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3669 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3670 	pSMB->Pad = 0;
3671 	pSMB->Fid = netfid;
3672 	in_len += byte_count;
3673 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3674 
3675 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3676 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3677 	if (rc) {
3678 		cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3679 	} else {
3680 		/* decode response */
3681 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3682 		/* BB also check enough total bytes returned */
3683 		if (rc || get_bcc(&pSMBr->hdr) < 2)
3684 			/* If rc should we check for EOPNOSUPP and
3685 			   disable the srvino flag? or in caller? */
3686 			rc = smb_EIO2(smb_eio_trace_getextattr_bcc_too_small,
3687 				      get_bcc(&pSMBr->hdr), 2);
3688 		else {
3689 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3690 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3691 			struct file_chattr_info *pfinfo;
3692 
3693 			if (count != 16) {
3694 				cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3695 				rc = smb_EIO2(smb_eio_trace_getextattr_inv_size,
3696 					      count, 16);
3697 				goto GetExtAttrOut;
3698 			}
3699 			pfinfo = (struct file_chattr_info *)
3700 				 (data_offset + (char *) &pSMBr->hdr.Protocol);
3701 			*pExtAttrBits = le64_to_cpu(pfinfo->mode);
3702 			*pMask = le64_to_cpu(pfinfo->mask);
3703 		}
3704 	}
3705 GetExtAttrOut:
3706 	cifs_buf_release(pSMB);
3707 	if (rc == -EAGAIN)
3708 		goto GetExtAttrRetry;
3709 	return rc;
3710 }
3711 
3712 #endif /* CONFIG_POSIX */
3713 
3714 /*
3715  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3716  * all NT TRANSACTS that we init here have total parm and data under about 400
3717  * bytes (to fit in small cifs buffer size), which is the case so far, it
3718  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3719  * returned setup area) and MaxParameterCount (returned parms size) must be set
3720  * by caller
3721  */
3722 static int
smb_init_nttransact(const __u16 sub_command,const int setup_count,const int parm_len,struct cifs_tcon * tcon,void ** ret_buf)3723 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3724 		   const int parm_len, struct cifs_tcon *tcon,
3725 		   void **ret_buf)
3726 {
3727 	int rc;
3728 	__u32 temp_offset;
3729 	struct smb_com_ntransact_req *pSMB;
3730 	unsigned int in_len;
3731 
3732 	rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3733 				(void **)&pSMB);
3734 	if (rc < 0)
3735 		return rc;
3736 	in_len = rc;
3737 	*ret_buf = (void *)pSMB;
3738 	pSMB->Reserved = 0;
3739 	pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3740 	pSMB->TotalDataCount  = 0;
3741 	pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3742 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3743 	pSMB->DataCount  = pSMB->TotalDataCount;
3744 	temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3745 		(setup_count * 2);
3746 	pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3747 	pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3748 	pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3749 	pSMB->SubCommand = cpu_to_le16(sub_command);
3750 	return in_len;
3751 }
3752 
3753 static int
validate_ntransact(char * buf,char ** ppparm,char ** ppdata,__u32 * pparmlen,__u32 * pdatalen)3754 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3755 		   __u32 *pparmlen, __u32 *pdatalen)
3756 {
3757 	char *end_of_smb;
3758 	__u32 data_count, data_offset, parm_count, parm_offset;
3759 	struct smb_com_ntransact_rsp *pSMBr;
3760 	u16 bcc;
3761 
3762 	*pdatalen = 0;
3763 	*pparmlen = 0;
3764 
3765 	if (buf == NULL)
3766 		return -EINVAL;
3767 
3768 	pSMBr = (struct smb_com_ntransact_rsp *)buf;
3769 
3770 	bcc = get_bcc(&pSMBr->hdr);
3771 	end_of_smb = 2 /* sizeof byte count */ + bcc +
3772 			(char *)&pSMBr->ByteCount;
3773 
3774 	data_offset = le32_to_cpu(pSMBr->DataOffset);
3775 	data_count = le32_to_cpu(pSMBr->DataCount);
3776 	parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3777 	parm_count = le32_to_cpu(pSMBr->ParameterCount);
3778 
3779 	*ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3780 	*ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3781 
3782 	/* should we also check that parm and data areas do not overlap? */
3783 	if (*ppparm > end_of_smb) {
3784 		cifs_dbg(FYI, "parms start after end of smb\n");
3785 		return -EINVAL;
3786 	} else if (parm_count + *ppparm > end_of_smb) {
3787 		cifs_dbg(FYI, "parm end after end of smb\n");
3788 		return -EINVAL;
3789 	} else if (*ppdata > end_of_smb) {
3790 		cifs_dbg(FYI, "data starts after end of smb\n");
3791 		return -EINVAL;
3792 	} else if (data_count + *ppdata > end_of_smb) {
3793 		cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3794 			 *ppdata, data_count, (data_count + *ppdata),
3795 			 end_of_smb, pSMBr);
3796 		return -EINVAL;
3797 	} else if (parm_count + data_count > bcc) {
3798 		cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3799 		return -EINVAL;
3800 	}
3801 	*pdatalen = data_count;
3802 	*pparmlen = parm_count;
3803 	return 0;
3804 }
3805 
3806 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3807 int
CIFSSMBGetCIFSACL(const unsigned int xid,struct cifs_tcon * tcon,__u16 fid,struct smb_ntsd ** acl_inf,__u32 * pbuflen,__u32 info)3808 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3809 		  struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info)
3810 {
3811 	int rc = 0;
3812 	int buf_type = 0;
3813 	QUERY_SEC_DESC_REQ *pSMB;
3814 	struct kvec iov[1];
3815 	struct kvec rsp_iov;
3816 	unsigned int in_len;
3817 
3818 	cifs_dbg(FYI, "GetCifsACL\n");
3819 
3820 	*pbuflen = 0;
3821 	*acl_inf = NULL;
3822 
3823 	rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3824 			8 /* parm len */, tcon, (void **) &pSMB);
3825 	if (rc < 0)
3826 		return rc;
3827 	in_len = rc;
3828 
3829 	pSMB->MaxParameterCount = cpu_to_le32(4);
3830 	/* BB TEST with big acls that might need to be e.g. larger than 16K */
3831 	pSMB->MaxSetupCount = 0;
3832 	pSMB->Fid = fid; /* file handle always le */
3833 	pSMB->AclFlags = cpu_to_le32(info);
3834 	pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3835 	in_len += 11;
3836 	iov[0].iov_base = (char *)pSMB;
3837 	iov[0].iov_len = in_len;
3838 
3839 	rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3840 			  0, &rsp_iov);
3841 	cifs_small_buf_release(pSMB);
3842 	cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3843 	if (rc) {
3844 		cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3845 	} else {                /* decode response */
3846 		__le32 *parm;
3847 		__u32 parm_len;
3848 		__u32 acl_len;
3849 		struct smb_com_ntransact_rsp *pSMBr;
3850 		char *pdata;
3851 
3852 /* validate_nttransact */
3853 		rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3854 					&pdata, &parm_len, pbuflen);
3855 		if (rc)
3856 			goto qsec_out;
3857 		pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3858 
3859 		cifs_dbg(FYI, "smb %p parm %p data %p\n",
3860 			 pSMBr, parm, *acl_inf);
3861 
3862 		if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3863 			rc = smb_EIO2(smb_eio_trace_getcifsacl_param_count,
3864 				      le32_to_cpu(pSMBr->ParameterCount), 4);
3865 			*pbuflen = 0;
3866 			goto qsec_out;
3867 		}
3868 
3869 /* BB check that data area is minimum length and as big as acl_len */
3870 
3871 		acl_len = le32_to_cpu(*parm);
3872 		if (acl_len != *pbuflen) {
3873 			cifs_dbg(VFS, "acl length %d does not match %d\n",
3874 				 acl_len, *pbuflen);
3875 			if (*pbuflen > acl_len)
3876 				*pbuflen = acl_len;
3877 		}
3878 
3879 		/* check if buffer is big enough for the acl
3880 		   header followed by the smallest SID */
3881 		if ((*pbuflen < sizeof(struct smb_ntsd) + 8) ||
3882 		    (*pbuflen >= 64 * 1024)) {
3883 			cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3884 			rc = -EINVAL;
3885 			*pbuflen = 0;
3886 		} else {
3887 			*acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3888 			if (*acl_inf == NULL) {
3889 				*pbuflen = 0;
3890 				rc = -ENOMEM;
3891 			}
3892 		}
3893 	}
3894 qsec_out:
3895 	free_rsp_buf(buf_type, rsp_iov.iov_base);
3896 	return rc;
3897 }
3898 
3899 int
CIFSSMBSetCIFSACL(const unsigned int xid,struct cifs_tcon * tcon,__u16 fid,struct smb_ntsd * pntsd,__u32 acllen,int aclflag)3900 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3901 			struct smb_ntsd *pntsd, __u32 acllen, int aclflag)
3902 {
3903 	__u16 byte_count, param_count, data_count, param_offset, data_offset;
3904 	int rc = 0;
3905 	int bytes_returned = 0;
3906 	SET_SEC_DESC_REQ *pSMB = NULL;
3907 	unsigned int in_len;
3908 	void *pSMBr;
3909 
3910 setCifsAclRetry:
3911 	rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3912 	if (rc < 0)
3913 		return rc;
3914 	in_len = rc;
3915 
3916 	pSMB->MaxSetupCount = 0;
3917 	pSMB->Reserved = 0;
3918 
3919 	param_count = 8;
3920 	param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid);
3921 	data_count = acllen;
3922 	data_offset = param_offset + param_count;
3923 	byte_count = 3 /* pad */  + param_count;
3924 
3925 	pSMB->DataCount = cpu_to_le32(data_count);
3926 	pSMB->TotalDataCount = pSMB->DataCount;
3927 	pSMB->MaxParameterCount = cpu_to_le32(4);
3928 	pSMB->MaxDataCount = cpu_to_le32(16384);
3929 	pSMB->ParameterCount = cpu_to_le32(param_count);
3930 	pSMB->ParameterOffset = cpu_to_le32(param_offset);
3931 	pSMB->TotalParameterCount = pSMB->ParameterCount;
3932 	pSMB->DataOffset = cpu_to_le32(data_offset);
3933 	pSMB->SetupCount = 0;
3934 	pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3935 	pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3936 
3937 	pSMB->Fid = fid; /* file handle always le */
3938 	pSMB->Reserved2 = 0;
3939 	pSMB->AclFlags = cpu_to_le32(aclflag);
3940 
3941 	if (pntsd && acllen) {
3942 		memcpy((char *)pSMBr + data_offset, pntsd, acllen);
3943 		in_len += byte_count + data_count;
3944 	} else
3945 		in_len += byte_count;
3946 
3947 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3948 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
3949 
3950 	cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3951 		 bytes_returned, rc);
3952 	if (rc)
3953 		cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3954 	cifs_buf_release(pSMB);
3955 
3956 	if (rc == -EAGAIN)
3957 		goto setCifsAclRetry;
3958 
3959 	return (rc);
3960 }
3961 
3962 
3963 /* Legacy Query Path Information call for lookup to old servers such
3964    as Win9x/WinME */
3965 int
SMBQueryInformation(const unsigned int xid,struct cifs_tcon * tcon,const char * search_name,FILE_ALL_INFO * data,const struct nls_table * nls_codepage,int remap)3966 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3967 		    const char *search_name, FILE_ALL_INFO *data,
3968 		    const struct nls_table *nls_codepage, int remap)
3969 {
3970 	QUERY_INFORMATION_REQ *pSMB;
3971 	QUERY_INFORMATION_RSP *pSMBr;
3972 	unsigned int in_len;
3973 	int rc = 0;
3974 	int bytes_returned;
3975 	int name_len;
3976 
3977 	cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3978 QInfRetry:
3979 	rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3980 		      (void **) &pSMBr);
3981 	if (rc < 0)
3982 		return rc;
3983 	in_len = rc;
3984 
3985 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3986 		name_len =
3987 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
3988 					   search_name, PATH_MAX, nls_codepage,
3989 					   remap);
3990 		name_len++;     /* trailing null */
3991 		name_len *= 2;
3992 	} else {
3993 		name_len = copy_path_name(pSMB->FileName, search_name);
3994 	}
3995 	pSMB->BufferFormat = 0x04;
3996 	name_len++; /* account for buffer type byte */
3997 	in_len += name_len;
3998 	pSMB->ByteCount = cpu_to_le16(name_len);
3999 
4000 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4001 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4002 	if (rc) {
4003 		cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4004 	} else if (data) {
4005 		struct timespec64 ts;
4006 		__u32 time = le32_to_cpu(pSMBr->last_write_time);
4007 
4008 		/* decode response */
4009 		/* BB FIXME - add time zone adjustment BB */
4010 		memset(data, 0, sizeof(FILE_ALL_INFO));
4011 		ts.tv_nsec = 0;
4012 		ts.tv_sec = time;
4013 		/* decode time fields */
4014 		data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4015 		data->LastWriteTime = data->ChangeTime;
4016 		data->LastAccessTime = 0;
4017 		data->AllocationSize =
4018 			cpu_to_le64(le32_to_cpu(pSMBr->size));
4019 		data->EndOfFile = data->AllocationSize;
4020 		data->Attributes =
4021 			cpu_to_le32(le16_to_cpu(pSMBr->attr));
4022 	} else {
4023 		/* bad buffer passed in */
4024 		rc = smb_EIO(smb_eio_trace_null_pointers);
4025 	}
4026 
4027 	cifs_buf_release(pSMB);
4028 
4029 	if (rc == -EAGAIN)
4030 		goto QInfRetry;
4031 
4032 	return rc;
4033 }
4034 
4035 int
CIFSSMBQFileInfo(const unsigned int xid,struct cifs_tcon * tcon,u16 netfid,FILE_ALL_INFO * pFindData)4036 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4037 		 u16 netfid, FILE_ALL_INFO *pFindData)
4038 {
4039 	struct smb_t2_qfi_req *pSMB = NULL;
4040 	struct smb_t2_qfi_rsp *pSMBr = NULL;
4041 	unsigned int in_len;
4042 	int rc = 0;
4043 	int bytes_returned;
4044 	__u16 params, byte_count;
4045 
4046 QFileInfoRetry:
4047 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4048 		      (void **) &pSMBr);
4049 	if (rc < 0)
4050 		return rc;
4051 	in_len = rc;
4052 
4053 	params = 2 /* level */ + 2 /* fid */;
4054 	pSMB->t2.TotalDataCount = 0;
4055 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4056 	/* BB find exact max data count below from sess structure BB */
4057 	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4058 	pSMB->t2.MaxSetupCount = 0;
4059 	pSMB->t2.Reserved = 0;
4060 	pSMB->t2.Flags = 0;
4061 	pSMB->t2.Timeout = 0;
4062 	pSMB->t2.Reserved2 = 0;
4063 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4064 					       Fid));
4065 	pSMB->t2.DataCount = 0;
4066 	pSMB->t2.DataOffset = 0;
4067 	pSMB->t2.SetupCount = 1;
4068 	pSMB->t2.Reserved3 = 0;
4069 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4070 	byte_count = params + 1 /* pad */ ;
4071 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4072 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4073 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4074 	pSMB->Pad = 0;
4075 	pSMB->Fid = netfid;
4076 	in_len += byte_count;
4077 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4078 
4079 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4080 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4081 	if (rc) {
4082 		cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4083 	} else {		/* decode response */
4084 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4085 
4086 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
4087 			rc = smb_EIO2(smb_eio_trace_qfileinfo_invalid,
4088 				      get_bcc(&pSMBr->hdr), 40);
4089 		else if (get_bcc(&pSMBr->hdr) < 40)
4090 			rc = smb_EIO2(smb_eio_trace_qfileinfo_bcc_too_small,
4091 				      get_bcc(&pSMBr->hdr), 40);
4092 		else if (pFindData) {
4093 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4094 			memcpy((char *) pFindData,
4095 			       (char *) &pSMBr->hdr.Protocol +
4096 			       data_offset, sizeof(FILE_ALL_INFO));
4097 		} else
4098 		    rc = -ENOMEM;
4099 	}
4100 	cifs_buf_release(pSMB);
4101 	if (rc == -EAGAIN)
4102 		goto QFileInfoRetry;
4103 
4104 	return rc;
4105 }
4106 
4107 int
CIFSSMBQPathInfo(const unsigned int xid,struct cifs_tcon * tcon,const char * search_name,FILE_ALL_INFO * data,int legacy,const struct nls_table * nls_codepage,int remap)4108 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4109 		 const char *search_name, FILE_ALL_INFO *data,
4110 		 int legacy /* old style infolevel */,
4111 		 const struct nls_table *nls_codepage, int remap)
4112 {
4113 	/* level 263 SMB_QUERY_FILE_ALL_INFO */
4114 	TRANSACTION2_QPI_REQ *pSMB = NULL;
4115 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
4116 	unsigned int in_len;
4117 	int rc = 0;
4118 	int bytes_returned;
4119 	int name_len;
4120 	__u16 params, byte_count;
4121 
4122 	/* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4123 QPathInfoRetry:
4124 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4125 		      (void **) &pSMBr);
4126 	if (rc < 0)
4127 		return rc;
4128 	in_len = rc;
4129 
4130 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4131 		name_len =
4132 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4133 				       PATH_MAX, nls_codepage, remap);
4134 		name_len++;	/* trailing null */
4135 		name_len *= 2;
4136 	} else {
4137 		name_len = copy_path_name(pSMB->FileName, search_name);
4138 	}
4139 
4140 	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4141 	pSMB->TotalDataCount = 0;
4142 	pSMB->MaxParameterCount = cpu_to_le16(2);
4143 	/* BB find exact max SMB PDU from sess structure BB */
4144 	pSMB->MaxDataCount = cpu_to_le16(4000);
4145 	pSMB->MaxSetupCount = 0;
4146 	pSMB->Reserved = 0;
4147 	pSMB->Flags = 0;
4148 	pSMB->Timeout = 0;
4149 	pSMB->Reserved2 = 0;
4150 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4151 		struct smb_com_transaction2_qpi_req, InformationLevel));
4152 	pSMB->DataCount = 0;
4153 	pSMB->DataOffset = 0;
4154 	pSMB->SetupCount = 1;
4155 	pSMB->Reserved3 = 0;
4156 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4157 	byte_count = params + 1 /* pad */ ;
4158 	pSMB->TotalParameterCount = cpu_to_le16(params);
4159 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4160 	if (legacy)
4161 		pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4162 	else
4163 		pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4164 	pSMB->Reserved4 = 0;
4165 	in_len += byte_count;
4166 	pSMB->ByteCount = cpu_to_le16(byte_count);
4167 
4168 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4169 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4170 	if (rc) {
4171 		cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4172 	} else {		/* decode response */
4173 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4174 
4175 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
4176 			rc = smb_EIO2(smb_eio_trace_qpathinfo_invalid,
4177 				      get_bcc(&pSMBr->hdr), 40);
4178 		else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4179 			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
4180 				      get_bcc(&pSMBr->hdr), 40);
4181 		else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4182 			/* 24 or 26 expected but we do not read last field */
4183 			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
4184 				      get_bcc(&pSMBr->hdr), 24);
4185 		else if (data) {
4186 			int size;
4187 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4188 
4189 			/*
4190 			 * On legacy responses we do not read the last field,
4191 			 * EAsize, fortunately since it varies by subdialect and
4192 			 * also note it differs on Set vs Get, ie two bytes or 4
4193 			 * bytes depending but we don't care here.
4194 			 */
4195 			if (legacy)
4196 				size = sizeof(FILE_INFO_STANDARD);
4197 			else
4198 				size = sizeof(FILE_ALL_INFO);
4199 			memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4200 			       data_offset, size);
4201 		} else
4202 		    rc = -ENOMEM;
4203 	}
4204 	cifs_buf_release(pSMB);
4205 	if (rc == -EAGAIN)
4206 		goto QPathInfoRetry;
4207 
4208 	return rc;
4209 }
4210 
4211 int
CIFSSMBUnixQFileInfo(const unsigned int xid,struct cifs_tcon * tcon,u16 netfid,FILE_UNIX_BASIC_INFO * pFindData)4212 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4213 		 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4214 {
4215 	struct smb_t2_qfi_req *pSMB = NULL;
4216 	struct smb_t2_qfi_rsp *pSMBr = NULL;
4217 	unsigned int in_len;
4218 	int rc = 0;
4219 	int bytes_returned;
4220 	__u16 params, byte_count;
4221 
4222 UnixQFileInfoRetry:
4223 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4224 		      (void **) &pSMBr);
4225 	if (rc < 0)
4226 		return rc;
4227 	in_len = rc;
4228 
4229 	params = 2 /* level */ + 2 /* fid */;
4230 	pSMB->t2.TotalDataCount = 0;
4231 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4232 	/* BB find exact max data count below from sess structure BB */
4233 	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4234 	pSMB->t2.MaxSetupCount = 0;
4235 	pSMB->t2.Reserved = 0;
4236 	pSMB->t2.Flags = 0;
4237 	pSMB->t2.Timeout = 0;
4238 	pSMB->t2.Reserved2 = 0;
4239 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4240 					       Fid));
4241 	pSMB->t2.DataCount = 0;
4242 	pSMB->t2.DataOffset = 0;
4243 	pSMB->t2.SetupCount = 1;
4244 	pSMB->t2.Reserved3 = 0;
4245 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4246 	byte_count = params + 1 /* pad */ ;
4247 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4248 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4249 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4250 	pSMB->Pad = 0;
4251 	pSMB->Fid = netfid;
4252 	in_len += byte_count;
4253 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4254 
4255 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4256 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4257 	if (rc) {
4258 		cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4259 	} else {		/* decode response */
4260 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4261 
4262 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4263 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4264 			rc = smb_EIO2(smb_eio_trace_unixqfileinfo_bcc_too_small,
4265 				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
4266 		} else {
4267 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4268 			memcpy((char *) pFindData,
4269 			       (char *) &pSMBr->hdr.Protocol +
4270 			       data_offset,
4271 			       sizeof(FILE_UNIX_BASIC_INFO));
4272 		}
4273 	}
4274 
4275 	cifs_buf_release(pSMB);
4276 	if (rc == -EAGAIN)
4277 		goto UnixQFileInfoRetry;
4278 
4279 	return rc;
4280 }
4281 
4282 int
CIFSSMBUnixQPathInfo(const unsigned int xid,struct cifs_tcon * tcon,const unsigned char * searchName,FILE_UNIX_BASIC_INFO * pFindData,const struct nls_table * nls_codepage,int remap)4283 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4284 		     const unsigned char *searchName,
4285 		     FILE_UNIX_BASIC_INFO *pFindData,
4286 		     const struct nls_table *nls_codepage, int remap)
4287 {
4288 /* SMB_QUERY_FILE_UNIX_BASIC */
4289 	TRANSACTION2_QPI_REQ *pSMB = NULL;
4290 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
4291 	unsigned int in_len;
4292 	int rc = 0;
4293 	int bytes_returned = 0;
4294 	int name_len;
4295 	__u16 params, byte_count;
4296 
4297 	cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4298 UnixQPathInfoRetry:
4299 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4300 		      (void **) &pSMBr);
4301 	if (rc < 0)
4302 		return rc;
4303 	in_len = rc;
4304 
4305 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4306 		name_len =
4307 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4308 				       PATH_MAX, nls_codepage, remap);
4309 		name_len++;	/* trailing null */
4310 		name_len *= 2;
4311 	} else {
4312 		name_len = copy_path_name(pSMB->FileName, searchName);
4313 	}
4314 
4315 	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4316 	pSMB->TotalDataCount = 0;
4317 	pSMB->MaxParameterCount = cpu_to_le16(2);
4318 	/* BB find exact max SMB PDU from sess structure BB */
4319 	pSMB->MaxDataCount = cpu_to_le16(4000);
4320 	pSMB->MaxSetupCount = 0;
4321 	pSMB->Reserved = 0;
4322 	pSMB->Flags = 0;
4323 	pSMB->Timeout = 0;
4324 	pSMB->Reserved2 = 0;
4325 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4326 		struct smb_com_transaction2_qpi_req, InformationLevel));
4327 	pSMB->DataCount = 0;
4328 	pSMB->DataOffset = 0;
4329 	pSMB->SetupCount = 1;
4330 	pSMB->Reserved3 = 0;
4331 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4332 	byte_count = params + 1 /* pad */ ;
4333 	pSMB->TotalParameterCount = cpu_to_le16(params);
4334 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4335 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4336 	pSMB->Reserved4 = 0;
4337 	in_len += byte_count;
4338 	pSMB->ByteCount = cpu_to_le16(byte_count);
4339 
4340 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4341 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4342 	if (rc) {
4343 		cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4344 	} else {		/* decode response */
4345 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4346 
4347 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4348 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4349 			rc = smb_EIO2(smb_eio_trace_unixqpathinfo_bcc_too_small,
4350 				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
4351 		} else {
4352 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4353 			memcpy((char *) pFindData,
4354 			       (char *) &pSMBr->hdr.Protocol +
4355 			       data_offset,
4356 			       sizeof(FILE_UNIX_BASIC_INFO));
4357 		}
4358 	}
4359 	cifs_buf_release(pSMB);
4360 	if (rc == -EAGAIN)
4361 		goto UnixQPathInfoRetry;
4362 
4363 	return rc;
4364 }
4365 
4366 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4367 int
CIFSFindFirst(const unsigned int xid,struct cifs_tcon * tcon,const char * searchName,struct cifs_sb_info * cifs_sb,__u16 * pnetfid,__u16 search_flags,struct cifs_search_info * psrch_inf,bool msearch)4368 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4369 	      const char *searchName, struct cifs_sb_info *cifs_sb,
4370 	      __u16 *pnetfid, __u16 search_flags,
4371 	      struct cifs_search_info *psrch_inf, bool msearch)
4372 {
4373 /* level 257 SMB_ */
4374 	TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4375 	TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4376 	T2_FFIRST_RSP_PARMS *parms;
4377 	struct nls_table *nls_codepage;
4378 	unsigned int in_len, lnoff;
4379 	__u16 params, byte_count;
4380 	int bytes_returned = 0;
4381 	int name_len, remap;
4382 	int rc = 0;
4383 
4384 	cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4385 
4386 findFirstRetry:
4387 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4388 		      (void **) &pSMBr);
4389 	if (rc < 0)
4390 		return rc;
4391 	in_len = rc;
4392 
4393 	nls_codepage = cifs_sb->local_nls;
4394 	remap = cifs_remap(cifs_sb);
4395 
4396 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4397 		name_len =
4398 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4399 				       PATH_MAX, nls_codepage, remap);
4400 		/* We can not add the asterisk earlier in case
4401 		it got remapped to 0xF03A as if it were part of the
4402 		directory name instead of a wildcard */
4403 		name_len *= 2;
4404 		if (msearch) {
4405 			pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4406 			pSMB->FileName[name_len+1] = 0;
4407 			pSMB->FileName[name_len+2] = '*';
4408 			pSMB->FileName[name_len+3] = 0;
4409 			name_len += 4; /* now the trailing null */
4410 			/* null terminate just in case */
4411 			pSMB->FileName[name_len] = 0;
4412 			pSMB->FileName[name_len+1] = 0;
4413 			name_len += 2;
4414 		} else if (!searchName[0]) {
4415 			pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb);
4416 			pSMB->FileName[1] = 0;
4417 			pSMB->FileName[2] = 0;
4418 			pSMB->FileName[3] = 0;
4419 			name_len = 4;
4420 		}
4421 	} else {
4422 		name_len = copy_path_name(pSMB->FileName, searchName);
4423 		if (msearch) {
4424 			if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4425 				name_len = PATH_MAX-2;
4426 			/* overwrite nul byte */
4427 			pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4428 			pSMB->FileName[name_len] = '*';
4429 			pSMB->FileName[name_len+1] = 0;
4430 			name_len += 2;
4431 		} else if (!searchName[0]) {
4432 			pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb);
4433 			pSMB->FileName[1] = 0;
4434 			name_len = 2;
4435 		}
4436 	}
4437 
4438 	params = 12 + name_len /* includes null */ ;
4439 	pSMB->TotalDataCount = 0;	/* no EAs */
4440 	pSMB->MaxParameterCount = cpu_to_le16(10);
4441 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4442 	pSMB->MaxSetupCount = 0;
4443 	pSMB->Reserved = 0;
4444 	pSMB->Flags = 0;
4445 	pSMB->Timeout = 0;
4446 	pSMB->Reserved2 = 0;
4447 	byte_count = params + 1 /* pad */ ;
4448 	pSMB->TotalParameterCount = cpu_to_le16(params);
4449 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4450 	pSMB->ParameterOffset = cpu_to_le16(
4451 	      offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes));
4452 	pSMB->DataCount = 0;
4453 	pSMB->DataOffset = 0;
4454 	pSMB->SetupCount = 1;	/* one byte, no need to make endian neutral */
4455 	pSMB->Reserved3 = 0;
4456 	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4457 	pSMB->SearchAttributes =
4458 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4459 			ATTR_DIRECTORY);
4460 	pSMB->SearchCount = cpu_to_le16(msearch ? CIFSMaxBufSize/sizeof(FILE_UNIX_INFO) : 1);
4461 	pSMB->SearchFlags = cpu_to_le16(search_flags);
4462 	pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4463 
4464 	/* BB what should we set StorageType to? Does it matter? BB */
4465 	pSMB->SearchStorageType = 0;
4466 	in_len += byte_count;
4467 	pSMB->ByteCount = cpu_to_le16(byte_count);
4468 
4469 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4470 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4471 	cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4472 
4473 	if (rc) {
4474 		/*
4475 		 * BB: add logic to retry regular search if Unix search rejected
4476 		 * unexpectedly by server.
4477 		 */
4478 		/* BB: add code to handle unsupported level rc */
4479 		cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4480 		cifs_buf_release(pSMB);
4481 		/*
4482 		 * BB: eventually could optimize out free and realloc of buf for
4483 		 * this case.
4484 		 */
4485 		if (rc == -EAGAIN)
4486 			goto findFirstRetry;
4487 		return rc;
4488 	}
4489 	/* decode response */
4490 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4491 	if (rc) {
4492 		cifs_buf_release(pSMB);
4493 		return rc;
4494 	}
4495 
4496 	psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4497 	psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4498 	psrch_inf->smallBuf = false;
4499 	psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
4500 		le16_to_cpu(pSMBr->t2.DataOffset);
4501 
4502 	parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
4503 					le16_to_cpu(pSMBr->t2.ParameterOffset));
4504 	psrch_inf->endOfSearch = !!parms->EndofSearch;
4505 
4506 	psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4507 	psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4508 		psrch_inf->entries_in_buffer;
4509 	lnoff = le16_to_cpu(parms->LastNameOffset);
4510 	if (CIFSMaxBufSize < lnoff) {
4511 		cifs_dbg(VFS, "ignoring corrupt resume name\n");
4512 		psrch_inf->last_entry = NULL;
4513 	} else {
4514 		psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4515 		if (pnetfid)
4516 			*pnetfid = parms->SearchHandle;
4517 	}
4518 	return 0;
4519 }
4520 
CIFSFindNext(const unsigned int xid,struct cifs_tcon * tcon,__u16 searchHandle,__u16 search_flags,struct cifs_search_info * psrch_inf)4521 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4522 		 __u16 searchHandle, __u16 search_flags,
4523 		 struct cifs_search_info *psrch_inf)
4524 {
4525 	TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4526 	TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4527 	T2_FNEXT_RSP_PARMS *parms;
4528 	unsigned int name_len, in_len;
4529 	unsigned int lnoff;
4530 	__u16 params, byte_count;
4531 	char *response_data;
4532 	int bytes_returned;
4533 	int rc = 0;
4534 
4535 	cifs_dbg(FYI, "In FindNext\n");
4536 
4537 	if (psrch_inf->endOfSearch)
4538 		return -ENOENT;
4539 
4540 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4541 		(void **) &pSMBr);
4542 	if (rc < 0)
4543 		return rc;
4544 	in_len = rc;
4545 
4546 	params = 14; /* includes 2 bytes of null string, converted to LE below*/
4547 	byte_count = 0;
4548 	pSMB->TotalDataCount = 0;       /* no EAs */
4549 	pSMB->MaxParameterCount = cpu_to_le16(8);
4550 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4551 	pSMB->MaxSetupCount = 0;
4552 	pSMB->Reserved = 0;
4553 	pSMB->Flags = 0;
4554 	pSMB->Timeout = 0;
4555 	pSMB->Reserved2 = 0;
4556 	pSMB->ParameterOffset =  cpu_to_le16(
4557 	      offsetof(struct smb_com_transaction2_fnext_req, SearchHandle));
4558 	pSMB->DataCount = 0;
4559 	pSMB->DataOffset = 0;
4560 	pSMB->SetupCount = 1;
4561 	pSMB->Reserved3 = 0;
4562 	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4563 	pSMB->SearchHandle = searchHandle;      /* always kept as le */
4564 	pSMB->SearchCount =
4565 		cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4566 	pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4567 	pSMB->ResumeKey = psrch_inf->resume_key;
4568 	pSMB->SearchFlags = cpu_to_le16(search_flags);
4569 
4570 	name_len = psrch_inf->resume_name_len;
4571 	params += name_len;
4572 	if (name_len < PATH_MAX) {
4573 		memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4574 		byte_count += name_len;
4575 		/* 14 byte parm len above enough for 2 byte null terminator */
4576 		pSMB->ResumeFileName[name_len] = 0;
4577 		pSMB->ResumeFileName[name_len+1] = 0;
4578 	} else {
4579 		cifs_buf_release(pSMB);
4580 		return -EINVAL;
4581 	}
4582 	byte_count = params + 1 /* pad */ ;
4583 	pSMB->TotalParameterCount = cpu_to_le16(params);
4584 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4585 	in_len += byte_count;
4586 	pSMB->ByteCount = cpu_to_le16(byte_count);
4587 
4588 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4589 			(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4590 	cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4591 
4592 	if (rc) {
4593 		cifs_buf_release(pSMB);
4594 		if (rc == -EBADF) {
4595 			psrch_inf->endOfSearch = true;
4596 			rc = 0; /* search probably was closed at end of search*/
4597 		} else {
4598 			cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4599 		}
4600 		return rc;
4601 	}
4602 
4603 	/* decode response */
4604 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4605 	if (rc) {
4606 		cifs_buf_release(pSMB);
4607 		return rc;
4608 	}
4609 	/* BB fixme add lock for file (srch_info) struct here */
4610 	psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4611 	response_data = (char *)&pSMBr->hdr.Protocol +
4612 		le16_to_cpu(pSMBr->t2.ParameterOffset);
4613 	parms = (T2_FNEXT_RSP_PARMS *)response_data;
4614 	response_data = (char *)&pSMBr->hdr.Protocol +
4615 		le16_to_cpu(pSMBr->t2.DataOffset);
4616 
4617 	if (psrch_inf->smallBuf)
4618 		cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4619 	else
4620 		cifs_buf_release(psrch_inf->ntwrk_buf_start);
4621 
4622 	psrch_inf->srch_entries_start = response_data;
4623 	psrch_inf->ntwrk_buf_start = (char *)pSMB;
4624 	psrch_inf->smallBuf = false;
4625 	psrch_inf->endOfSearch = !!parms->EndofSearch;
4626 	psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4627 	psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4628 	lnoff = le16_to_cpu(parms->LastNameOffset);
4629 	if (CIFSMaxBufSize < lnoff) {
4630 		cifs_dbg(VFS, "ignoring corrupt resume name\n");
4631 		psrch_inf->last_entry = NULL;
4632 	} else {
4633 		psrch_inf->last_entry =
4634 			psrch_inf->srch_entries_start + lnoff;
4635 	}
4636 	/* BB fixme add unlock here */
4637 
4638 	/*
4639 	 * BB: On error, should we leave previous search buf
4640 	 * (and count and last entry fields) intact or free the previous one?
4641 	 *
4642 	 * Note: On -EAGAIN error only caller can retry on handle based calls
4643 	 * since file handle passed in no longer valid.
4644 	 */
4645 	return 0;
4646 }
4647 
4648 int
CIFSFindClose(const unsigned int xid,struct cifs_tcon * tcon,const __u16 searchHandle)4649 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4650 	      const __u16 searchHandle)
4651 {
4652 	int rc = 0;
4653 	FINDCLOSE_REQ *pSMB = NULL;
4654 	unsigned int in_len;
4655 
4656 	cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4657 	rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4658 
4659 	/* no sense returning error if session restarted
4660 		as file handle has been closed */
4661 	if (rc == -EAGAIN)
4662 		return 0;
4663 	if (rc < 0)
4664 		return rc;
4665 	in_len = rc;
4666 
4667 	pSMB->FileID = searchHandle;
4668 	pSMB->ByteCount = 0;
4669 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
4670 	cifs_small_buf_release(pSMB);
4671 	if (rc)
4672 		cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4673 
4674 	cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4675 
4676 	/* Since session is dead, search handle closed on server already */
4677 	if (rc == -EAGAIN)
4678 		rc = 0;
4679 
4680 	return rc;
4681 }
4682 
4683 int
CIFSGetSrvInodeNumber(const unsigned int xid,struct cifs_tcon * tcon,const char * search_name,__u64 * inode_number,const struct nls_table * nls_codepage,int remap)4684 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4685 		      const char *search_name, __u64 *inode_number,
4686 		      const struct nls_table *nls_codepage, int remap)
4687 {
4688 	int rc = 0;
4689 	TRANSACTION2_QPI_REQ *pSMB = NULL;
4690 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
4691 	unsigned int in_len;
4692 	int name_len, bytes_returned;
4693 	__u16 params, byte_count;
4694 
4695 	cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4696 	if (tcon == NULL)
4697 		return -ENODEV;
4698 
4699 GetInodeNumberRetry:
4700 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4701 		      (void **) &pSMBr);
4702 	if (rc < 0)
4703 		return rc;
4704 	in_len = rc;
4705 
4706 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4707 		name_len =
4708 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
4709 					   search_name, PATH_MAX, nls_codepage,
4710 					   remap);
4711 		name_len++;     /* trailing null */
4712 		name_len *= 2;
4713 	} else {
4714 		name_len = copy_path_name(pSMB->FileName, search_name);
4715 	}
4716 
4717 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4718 	pSMB->TotalDataCount = 0;
4719 	pSMB->MaxParameterCount = cpu_to_le16(2);
4720 	/* BB find exact max data count below from sess structure BB */
4721 	pSMB->MaxDataCount = cpu_to_le16(4000);
4722 	pSMB->MaxSetupCount = 0;
4723 	pSMB->Reserved = 0;
4724 	pSMB->Flags = 0;
4725 	pSMB->Timeout = 0;
4726 	pSMB->Reserved2 = 0;
4727 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4728 		struct smb_com_transaction2_qpi_req, InformationLevel));
4729 	pSMB->DataCount = 0;
4730 	pSMB->DataOffset = 0;
4731 	pSMB->SetupCount = 1;
4732 	pSMB->Reserved3 = 0;
4733 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4734 	byte_count = params + 1 /* pad */ ;
4735 	pSMB->TotalParameterCount = cpu_to_le16(params);
4736 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4737 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4738 	pSMB->Reserved4 = 0;
4739 	in_len += byte_count;
4740 	pSMB->ByteCount = cpu_to_le16(byte_count);
4741 
4742 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4743 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4744 	if (rc) {
4745 		cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4746 	} else {
4747 		/* decode response */
4748 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4749 		/* BB also check enough total bytes returned */
4750 		if (rc || get_bcc(&pSMBr->hdr) < 2)
4751 			/* If rc should we check for EOPNOSUPP and
4752 			disable the srvino flag? or in caller? */
4753 			rc = smb_EIO2(smb_eio_trace_getsrvinonum_bcc_too_small,
4754 				      get_bcc(&pSMBr->hdr), 2);
4755 		else {
4756 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4757 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4758 			struct file_internal_info *pfinfo;
4759 			/* BB Do we need a cast or hash here ? */
4760 			if (count < 8) {
4761 				cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4762 				rc = smb_EIO2(smb_eio_trace_getsrvinonum_size,
4763 					      count, 8);
4764 				goto GetInodeNumOut;
4765 			}
4766 			pfinfo = (struct file_internal_info *)
4767 				(data_offset + (char *) &pSMBr->hdr.Protocol);
4768 			*inode_number = le64_to_cpu(pfinfo->UniqueId);
4769 		}
4770 	}
4771 GetInodeNumOut:
4772 	cifs_buf_release(pSMB);
4773 	if (rc == -EAGAIN)
4774 		goto GetInodeNumberRetry;
4775 	return rc;
4776 }
4777 
4778 int
CIFSGetDFSRefer(const unsigned int xid,struct cifs_ses * ses,const char * search_name,struct dfs_info3_param ** target_nodes,unsigned int * num_of_nodes,const struct nls_table * nls_codepage,int remap)4779 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4780 		const char *search_name, struct dfs_info3_param **target_nodes,
4781 		unsigned int *num_of_nodes,
4782 		const struct nls_table *nls_codepage, int remap)
4783 {
4784 /* TRANS2_GET_DFS_REFERRAL */
4785 	TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4786 	TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4787 	unsigned int in_len;
4788 	int rc = 0;
4789 	int bytes_returned;
4790 	int name_len;
4791 	__u16 params, byte_count;
4792 	*num_of_nodes = 0;
4793 	*target_nodes = NULL;
4794 
4795 	cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4796 	if (ses == NULL || ses->tcon_ipc == NULL)
4797 		return -ENODEV;
4798 
4799 getDFSRetry:
4800 	/*
4801 	 * Use smb_init_no_reconnect() instead of smb_init() as
4802 	 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4803 	 * causing an infinite recursion.
4804 	 */
4805 	rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4806 		      (void **)&pSMB, (void **)&pSMBr);
4807 	if (rc < 0)
4808 		return rc;
4809 	in_len = rc;
4810 
4811 	/* server pointer checked in called function,
4812 	but should never be null here anyway */
4813 	pSMB->hdr.Mid = get_next_mid(ses->server);
4814 	pSMB->hdr.Tid = ses->tcon_ipc->tid;
4815 	pSMB->hdr.Uid = ses->Suid;
4816 	if (ses->capabilities & CAP_STATUS32)
4817 		pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4818 	if (ses->capabilities & CAP_DFS)
4819 		pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4820 
4821 	if (ses->capabilities & CAP_UNICODE) {
4822 		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4823 		name_len =
4824 		    cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4825 				       search_name, PATH_MAX, nls_codepage,
4826 				       remap);
4827 		name_len++;	/* trailing null */
4828 		name_len *= 2;
4829 	} else {	/* BB improve the check for buffer overruns BB */
4830 		name_len = copy_path_name(pSMB->RequestFileName, search_name);
4831 	}
4832 
4833 	if (ses->server->sign)
4834 		pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4835 
4836 	pSMB->hdr.Uid = ses->Suid;
4837 
4838 	params = 2 /* level */  + name_len /*includes null */ ;
4839 	pSMB->TotalDataCount = 0;
4840 	pSMB->DataCount = 0;
4841 	pSMB->DataOffset = 0;
4842 	pSMB->MaxParameterCount = 0;
4843 	/* BB find exact max SMB PDU from sess structure BB */
4844 	pSMB->MaxDataCount = cpu_to_le16(4000);
4845 	pSMB->MaxSetupCount = 0;
4846 	pSMB->Reserved = 0;
4847 	pSMB->Flags = 0;
4848 	pSMB->Timeout = 0;
4849 	pSMB->Reserved2 = 0;
4850 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4851 	  struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel));
4852 	pSMB->SetupCount = 1;
4853 	pSMB->Reserved3 = 0;
4854 	pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4855 	byte_count = params + 3 /* pad */ ;
4856 	pSMB->ParameterCount = cpu_to_le16(params);
4857 	pSMB->TotalParameterCount = pSMB->ParameterCount;
4858 	pSMB->MaxReferralLevel = cpu_to_le16(3);
4859 	in_len += byte_count;
4860 	pSMB->ByteCount = cpu_to_le16(byte_count);
4861 
4862 	rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len,
4863 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4864 	if (rc) {
4865 		cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4866 		goto GetDFSRefExit;
4867 	}
4868 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4869 
4870 	/* BB Also check if enough total bytes returned? */
4871 	if (rc || get_bcc(&pSMBr->hdr) < 17) {
4872 		rc = smb_EIO2(smb_eio_trace_getdfsrefer_bcc_too_small,
4873 			      get_bcc(&pSMBr->hdr), 17);
4874 		goto GetDFSRefExit;
4875 	}
4876 
4877 	cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4878 		 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4879 
4880 	/* parse returned result into more usable form */
4881 	rc = parse_dfs_referrals(&pSMBr->dfs_data,
4882 				 le16_to_cpu(pSMBr->t2.DataCount),
4883 				 num_of_nodes, target_nodes, nls_codepage,
4884 				 remap, search_name,
4885 				 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4886 
4887 GetDFSRefExit:
4888 	cifs_buf_release(pSMB);
4889 
4890 	if (rc == -EAGAIN)
4891 		goto getDFSRetry;
4892 
4893 	return rc;
4894 }
4895 
4896 /* Query File System Info such as free space to old servers such as Win 9x */
4897 int
SMBOldQFSInfo(const unsigned int xid,struct cifs_tcon * tcon,struct kstatfs * FSData)4898 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4899 	      struct kstatfs *FSData)
4900 {
4901 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4902 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4903 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4904 	FILE_SYSTEM_ALLOC_INFO *response_data;
4905 	unsigned int in_len;
4906 	int rc = 0;
4907 	int bytes_returned = 0;
4908 	__u16 params, byte_count;
4909 
4910 	cifs_dbg(FYI, "OldQFSInfo\n");
4911 oldQFSInfoRetry:
4912 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4913 		(void **) &pSMBr);
4914 	if (rc < 0)
4915 		return rc;
4916 	in_len = rc;
4917 
4918 	params = 2;     /* level */
4919 	pSMB->TotalDataCount = 0;
4920 	pSMB->MaxParameterCount = cpu_to_le16(2);
4921 	pSMB->MaxDataCount = cpu_to_le16(1000);
4922 	pSMB->MaxSetupCount = 0;
4923 	pSMB->Reserved = 0;
4924 	pSMB->Flags = 0;
4925 	pSMB->Timeout = 0;
4926 	pSMB->Reserved2 = 0;
4927 	byte_count = params + 1 /* pad */ ;
4928 	pSMB->TotalParameterCount = cpu_to_le16(params);
4929 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4930 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4931 		struct smb_com_transaction2_qfsi_req, InformationLevel));
4932 	pSMB->DataCount = 0;
4933 	pSMB->DataOffset = 0;
4934 	pSMB->SetupCount = 1;
4935 	pSMB->Reserved3 = 0;
4936 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4937 	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4938 	in_len += byte_count;
4939 	pSMB->ByteCount = cpu_to_le16(byte_count);
4940 
4941 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4942 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4943 	if (rc) {
4944 		cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4945 	} else {                /* decode response */
4946 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4947 
4948 		if (rc || get_bcc(&pSMBr->hdr) < 18)
4949 			rc = smb_EIO2(smb_eio_trace_oldqfsinfo_bcc_too_small,
4950 				      get_bcc(&pSMBr->hdr), 18);
4951 		else {
4952 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4953 			cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4954 				 get_bcc(&pSMBr->hdr), data_offset);
4955 
4956 			response_data = (FILE_SYSTEM_ALLOC_INFO *)
4957 				(((char *) &pSMBr->hdr.Protocol) + data_offset);
4958 			FSData->f_bsize =
4959 				le16_to_cpu(response_data->BytesPerSector) *
4960 				le32_to_cpu(response_data->
4961 					SectorsPerAllocationUnit);
4962 			/*
4963 			 * much prefer larger but if server doesn't report
4964 			 * a valid size than 4K is a reasonable minimum
4965 			 */
4966 			if (FSData->f_bsize < 512)
4967 				FSData->f_bsize = 4096;
4968 
4969 			FSData->f_blocks =
4970 			       le32_to_cpu(response_data->TotalAllocationUnits);
4971 			FSData->f_bfree = FSData->f_bavail =
4972 				le32_to_cpu(response_data->FreeAllocationUnits);
4973 			cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4974 				 (unsigned long long)FSData->f_blocks,
4975 				 (unsigned long long)FSData->f_bfree,
4976 				 FSData->f_bsize);
4977 		}
4978 	}
4979 	cifs_buf_release(pSMB);
4980 
4981 	if (rc == -EAGAIN)
4982 		goto oldQFSInfoRetry;
4983 
4984 	return rc;
4985 }
4986 
4987 int
CIFSSMBQFSInfo(const unsigned int xid,struct cifs_tcon * tcon,struct kstatfs * FSData)4988 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4989 	       struct kstatfs *FSData)
4990 {
4991 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4992 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4993 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4994 	FILE_SYSTEM_SIZE_INFO *response_data;
4995 	unsigned int in_len;
4996 	int rc = 0;
4997 	int bytes_returned = 0;
4998 	__u16 params, byte_count;
4999 
5000 	cifs_dbg(FYI, "In QFSInfo\n");
5001 QFSInfoRetry:
5002 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5003 		      (void **) &pSMBr);
5004 	if (rc < 0)
5005 		return rc;
5006 	in_len = rc;
5007 
5008 	params = 2;	/* level */
5009 	pSMB->TotalDataCount = 0;
5010 	pSMB->MaxParameterCount = cpu_to_le16(2);
5011 	pSMB->MaxDataCount = cpu_to_le16(1000);
5012 	pSMB->MaxSetupCount = 0;
5013 	pSMB->Reserved = 0;
5014 	pSMB->Flags = 0;
5015 	pSMB->Timeout = 0;
5016 	pSMB->Reserved2 = 0;
5017 	byte_count = params + 1 /* pad */ ;
5018 	pSMB->TotalParameterCount = cpu_to_le16(params);
5019 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5020 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5021 		struct smb_com_transaction2_qfsi_req, InformationLevel));
5022 	pSMB->DataCount = 0;
5023 	pSMB->DataOffset = 0;
5024 	pSMB->SetupCount = 1;
5025 	pSMB->Reserved3 = 0;
5026 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5027 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5028 	in_len += byte_count;
5029 	pSMB->ByteCount = cpu_to_le16(byte_count);
5030 
5031 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5032 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5033 	if (rc) {
5034 		cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5035 	} else {		/* decode response */
5036 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5037 
5038 		if (rc || get_bcc(&pSMBr->hdr) < 24)
5039 			rc = smb_EIO2(smb_eio_trace_qfsinfo_bcc_too_small,
5040 				      get_bcc(&pSMBr->hdr), 24);
5041 		else {
5042 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5043 
5044 			response_data =
5045 			    (FILE_SYSTEM_SIZE_INFO
5046 			     *) (((char *) &pSMBr->hdr.Protocol) +
5047 				 data_offset);
5048 			FSData->f_bsize =
5049 			    le32_to_cpu(response_data->BytesPerSector) *
5050 			    le32_to_cpu(response_data->
5051 					SectorsPerAllocationUnit);
5052 			/*
5053 			 * much prefer larger but if server doesn't report
5054 			 * a valid size than 4K is a reasonable minimum
5055 			 */
5056 			if (FSData->f_bsize < 512)
5057 				FSData->f_bsize = 4096;
5058 
5059 			FSData->f_blocks =
5060 			    le64_to_cpu(response_data->TotalAllocationUnits);
5061 			FSData->f_bfree = FSData->f_bavail =
5062 			    le64_to_cpu(response_data->AvailableAllocationUnits);
5063 			cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
5064 				 (unsigned long long)FSData->f_blocks,
5065 				 (unsigned long long)FSData->f_bfree,
5066 				 FSData->f_bsize);
5067 		}
5068 	}
5069 	cifs_buf_release(pSMB);
5070 
5071 	if (rc == -EAGAIN)
5072 		goto QFSInfoRetry;
5073 
5074 	return rc;
5075 }
5076 
5077 int
CIFSSMBQFSAttributeInfo(const unsigned int xid,struct cifs_tcon * tcon)5078 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5079 {
5080 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5081 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5082 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5083 	FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5084 	unsigned int in_len;
5085 	int rc = 0;
5086 	int bytes_returned = 0;
5087 	__u16 params, byte_count;
5088 
5089 	cifs_dbg(FYI, "In QFSAttributeInfo\n");
5090 QFSAttributeRetry:
5091 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5092 		      (void **) &pSMBr);
5093 	if (rc < 0)
5094 		return rc;
5095 	in_len = rc;
5096 
5097 	params = 2;	/* level */
5098 	pSMB->TotalDataCount = 0;
5099 	pSMB->MaxParameterCount = cpu_to_le16(2);
5100 	/* BB find exact max SMB PDU from sess structure BB */
5101 	pSMB->MaxDataCount = cpu_to_le16(1000);
5102 	pSMB->MaxSetupCount = 0;
5103 	pSMB->Reserved = 0;
5104 	pSMB->Flags = 0;
5105 	pSMB->Timeout = 0;
5106 	pSMB->Reserved2 = 0;
5107 	byte_count = params + 1 /* pad */ ;
5108 	pSMB->TotalParameterCount = cpu_to_le16(params);
5109 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5110 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5111 		struct smb_com_transaction2_qfsi_req, InformationLevel));
5112 	pSMB->DataCount = 0;
5113 	pSMB->DataOffset = 0;
5114 	pSMB->SetupCount = 1;
5115 	pSMB->Reserved3 = 0;
5116 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5117 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5118 	in_len += byte_count;
5119 	pSMB->ByteCount = cpu_to_le16(byte_count);
5120 
5121 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5122 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5123 	if (rc) {
5124 		cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5125 	} else {		/* decode response */
5126 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5127 
5128 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
5129 			/* BB also check if enough bytes returned */
5130 			rc = smb_EIO2(smb_eio_trace_qfsattrinfo_bcc_too_small,
5131 				      get_bcc(&pSMBr->hdr), 13);
5132 		} else {
5133 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5134 			response_data =
5135 			    (FILE_SYSTEM_ATTRIBUTE_INFO
5136 			     *) (((char *) &pSMBr->hdr.Protocol) +
5137 				 data_offset);
5138 			memcpy(&tcon->fsAttrInfo, response_data,
5139 			       sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5140 		}
5141 	}
5142 	cifs_buf_release(pSMB);
5143 
5144 	if (rc == -EAGAIN)
5145 		goto QFSAttributeRetry;
5146 
5147 	return rc;
5148 }
5149 
5150 int
CIFSSMBQFSDeviceInfo(const unsigned int xid,struct cifs_tcon * tcon)5151 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5152 {
5153 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5154 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5155 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5156 	FILE_SYSTEM_DEVICE_INFO *response_data;
5157 	unsigned int in_len;
5158 	int rc = 0;
5159 	int bytes_returned = 0;
5160 	__u16 params, byte_count;
5161 
5162 	cifs_dbg(FYI, "In QFSDeviceInfo\n");
5163 QFSDeviceRetry:
5164 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5165 		      (void **) &pSMBr);
5166 	if (rc < 0)
5167 		return rc;
5168 	in_len = rc;
5169 
5170 	params = 2;	/* level */
5171 	pSMB->TotalDataCount = 0;
5172 	pSMB->MaxParameterCount = cpu_to_le16(2);
5173 	/* BB find exact max SMB PDU from sess structure BB */
5174 	pSMB->MaxDataCount = cpu_to_le16(1000);
5175 	pSMB->MaxSetupCount = 0;
5176 	pSMB->Reserved = 0;
5177 	pSMB->Flags = 0;
5178 	pSMB->Timeout = 0;
5179 	pSMB->Reserved2 = 0;
5180 	byte_count = params + 1 /* pad */ ;
5181 	pSMB->TotalParameterCount = cpu_to_le16(params);
5182 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5183 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5184 		struct smb_com_transaction2_qfsi_req, InformationLevel));
5185 
5186 	pSMB->DataCount = 0;
5187 	pSMB->DataOffset = 0;
5188 	pSMB->SetupCount = 1;
5189 	pSMB->Reserved3 = 0;
5190 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5191 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5192 	in_len += byte_count;
5193 	pSMB->ByteCount = cpu_to_le16(byte_count);
5194 
5195 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5196 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5197 	if (rc) {
5198 		cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5199 	} else {		/* decode response */
5200 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5201 
5202 		if (rc || get_bcc(&pSMBr->hdr) <
5203 			  sizeof(FILE_SYSTEM_DEVICE_INFO))
5204 			rc = smb_EIO2(smb_eio_trace_qfsdevinfo_bcc_too_small,
5205 				      get_bcc(&pSMBr->hdr),
5206 				      sizeof(FILE_SYSTEM_DEVICE_INFO));
5207 		else {
5208 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5209 			response_data =
5210 			    (FILE_SYSTEM_DEVICE_INFO *)
5211 				(((char *) &pSMBr->hdr.Protocol) +
5212 				 data_offset);
5213 			memcpy(&tcon->fsDevInfo, response_data,
5214 			       sizeof(FILE_SYSTEM_DEVICE_INFO));
5215 		}
5216 	}
5217 	cifs_buf_release(pSMB);
5218 
5219 	if (rc == -EAGAIN)
5220 		goto QFSDeviceRetry;
5221 
5222 	return rc;
5223 }
5224 
5225 int
CIFSSMBQFSUnixInfo(const unsigned int xid,struct cifs_tcon * tcon)5226 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5227 {
5228 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5229 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5230 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5231 	FILE_SYSTEM_UNIX_INFO *response_data;
5232 	unsigned int in_len;
5233 	int rc = 0;
5234 	int bytes_returned = 0;
5235 	__u16 params, byte_count;
5236 
5237 	cifs_dbg(FYI, "In QFSUnixInfo\n");
5238 QFSUnixRetry:
5239 	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5240 				   (void **) &pSMB, (void **) &pSMBr);
5241 	if (rc < 0)
5242 		return rc;
5243 	in_len = rc;
5244 
5245 	params = 2;	/* level */
5246 	pSMB->TotalDataCount = 0;
5247 	pSMB->DataCount = 0;
5248 	pSMB->DataOffset = 0;
5249 	pSMB->MaxParameterCount = cpu_to_le16(2);
5250 	/* BB find exact max SMB PDU from sess structure BB */
5251 	pSMB->MaxDataCount = cpu_to_le16(100);
5252 	pSMB->MaxSetupCount = 0;
5253 	pSMB->Reserved = 0;
5254 	pSMB->Flags = 0;
5255 	pSMB->Timeout = 0;
5256 	pSMB->Reserved2 = 0;
5257 	byte_count = params + 1 /* pad */ ;
5258 	pSMB->ParameterCount = cpu_to_le16(params);
5259 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5260 	pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5261 			smb_com_transaction2_qfsi_req, InformationLevel));
5262 	pSMB->SetupCount = 1;
5263 	pSMB->Reserved3 = 0;
5264 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5265 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5266 	in_len += byte_count;
5267 	pSMB->ByteCount = cpu_to_le16(byte_count);
5268 
5269 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5270 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5271 	if (rc) {
5272 		cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5273 	} else {		/* decode response */
5274 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5275 
5276 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
5277 			rc = smb_EIO2(smb_eio_trace_qfsunixinfo_bcc_too_small,
5278 				      get_bcc(&pSMBr->hdr), 13);
5279 		} else {
5280 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5281 			response_data =
5282 			    (FILE_SYSTEM_UNIX_INFO
5283 			     *) (((char *) &pSMBr->hdr.Protocol) +
5284 				 data_offset);
5285 			memcpy(&tcon->fsUnixInfo, response_data,
5286 			       sizeof(FILE_SYSTEM_UNIX_INFO));
5287 		}
5288 	}
5289 	cifs_buf_release(pSMB);
5290 
5291 	if (rc == -EAGAIN)
5292 		goto QFSUnixRetry;
5293 
5294 
5295 	return rc;
5296 }
5297 
5298 int
CIFSSMBSetFSUnixInfo(const unsigned int xid,struct cifs_tcon * tcon,__u64 cap)5299 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5300 {
5301 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5302 	TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5303 	TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5304 	unsigned int in_len;
5305 	int rc = 0;
5306 	int bytes_returned = 0;
5307 	__u16 params, param_offset, offset, byte_count;
5308 
5309 	cifs_dbg(FYI, "In SETFSUnixInfo\n");
5310 SETFSUnixRetry:
5311 	/* BB switch to small buf init to save memory */
5312 	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5313 					(void **) &pSMB, (void **) &pSMBr);
5314 	if (rc < 0)
5315 		return rc;
5316 	in_len = rc;
5317 
5318 	params = 4;	/* 2 bytes zero followed by info level. */
5319 	pSMB->MaxSetupCount = 0;
5320 	pSMB->Reserved = 0;
5321 	pSMB->Flags = 0;
5322 	pSMB->Timeout = 0;
5323 	pSMB->Reserved2 = 0;
5324 	param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum);
5325 	offset = param_offset + params;
5326 
5327 	pSMB->MaxParameterCount = cpu_to_le16(4);
5328 	/* BB find exact max SMB PDU from sess structure BB */
5329 	pSMB->MaxDataCount = cpu_to_le16(100);
5330 	pSMB->SetupCount = 1;
5331 	pSMB->Reserved3 = 0;
5332 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5333 	byte_count = 1 /* pad */ + params + 12;
5334 
5335 	pSMB->DataCount = cpu_to_le16(12);
5336 	pSMB->ParameterCount = cpu_to_le16(params);
5337 	pSMB->TotalDataCount = pSMB->DataCount;
5338 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5339 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5340 	pSMB->DataOffset = cpu_to_le16(offset);
5341 
5342 	/* Params. */
5343 	pSMB->FileNum = 0;
5344 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5345 
5346 	/* Data. */
5347 	pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5348 	pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5349 	pSMB->ClientUnixCap = cpu_to_le64(cap);
5350 
5351 	in_len += byte_count;
5352 	pSMB->ByteCount = cpu_to_le16(byte_count);
5353 
5354 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5355 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5356 	if (rc) {
5357 		cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5358 	} else {		/* decode response */
5359 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5360 		if (rc)
5361 			rc = -EIO;	/* bad smb */
5362 	}
5363 	cifs_buf_release(pSMB);
5364 
5365 	if (rc == -EAGAIN)
5366 		goto SETFSUnixRetry;
5367 
5368 	return rc;
5369 }
5370 
5371 
5372 
5373 int
CIFSSMBQFSPosixInfo(const unsigned int xid,struct cifs_tcon * tcon,struct kstatfs * FSData)5374 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5375 		   struct kstatfs *FSData)
5376 {
5377 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5378 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5379 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5380 	FILE_SYSTEM_POSIX_INFO *response_data;
5381 	unsigned int in_len;
5382 	int rc = 0;
5383 	int bytes_returned = 0;
5384 	__u16 params, byte_count;
5385 
5386 	cifs_dbg(FYI, "In QFSPosixInfo\n");
5387 QFSPosixRetry:
5388 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5389 		      (void **) &pSMBr);
5390 	if (rc < 0)
5391 		return rc;
5392 	in_len = rc;
5393 
5394 	params = 2;	/* level */
5395 	pSMB->TotalDataCount = 0;
5396 	pSMB->DataCount = 0;
5397 	pSMB->DataOffset = 0;
5398 	pSMB->MaxParameterCount = cpu_to_le16(2);
5399 	/* BB find exact max SMB PDU from sess structure BB */
5400 	pSMB->MaxDataCount = cpu_to_le16(100);
5401 	pSMB->MaxSetupCount = 0;
5402 	pSMB->Reserved = 0;
5403 	pSMB->Flags = 0;
5404 	pSMB->Timeout = 0;
5405 	pSMB->Reserved2 = 0;
5406 	byte_count = params + 1 /* pad */ ;
5407 	pSMB->ParameterCount = cpu_to_le16(params);
5408 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5409 	pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5410 			smb_com_transaction2_qfsi_req, InformationLevel));
5411 	pSMB->SetupCount = 1;
5412 	pSMB->Reserved3 = 0;
5413 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5414 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5415 	in_len += byte_count;
5416 	pSMB->ByteCount = cpu_to_le16(byte_count);
5417 
5418 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5419 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5420 	if (rc) {
5421 		cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5422 	} else {		/* decode response */
5423 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5424 
5425 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
5426 			rc = smb_EIO2(smb_eio_trace_qfsposixinfo_bcc_too_small,
5427 				      get_bcc(&pSMBr->hdr), 13);
5428 		} else {
5429 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5430 			response_data =
5431 			    (FILE_SYSTEM_POSIX_INFO
5432 			     *) (((char *) &pSMBr->hdr.Protocol) +
5433 				 data_offset);
5434 			FSData->f_bsize =
5435 					le32_to_cpu(response_data->BlockSize);
5436 			/*
5437 			 * much prefer larger but if server doesn't report
5438 			 * a valid size than 4K is a reasonable minimum
5439 			 */
5440 			if (FSData->f_bsize < 512)
5441 				FSData->f_bsize = 4096;
5442 
5443 			FSData->f_blocks =
5444 					le64_to_cpu(response_data->TotalBlocks);
5445 			FSData->f_bfree =
5446 			    le64_to_cpu(response_data->BlocksAvail);
5447 			if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5448 				FSData->f_bavail = FSData->f_bfree;
5449 			} else {
5450 				FSData->f_bavail =
5451 				    le64_to_cpu(response_data->UserBlocksAvail);
5452 			}
5453 			if (response_data->TotalFileNodes != cpu_to_le64(-1))
5454 				FSData->f_files =
5455 				     le64_to_cpu(response_data->TotalFileNodes);
5456 			if (response_data->FreeFileNodes != cpu_to_le64(-1))
5457 				FSData->f_ffree =
5458 				      le64_to_cpu(response_data->FreeFileNodes);
5459 		}
5460 	}
5461 	cifs_buf_release(pSMB);
5462 
5463 	if (rc == -EAGAIN)
5464 		goto QFSPosixRetry;
5465 
5466 	return rc;
5467 }
5468 
5469 
5470 /*
5471  * We can not use write of zero bytes trick to set file size due to need for
5472  * large file support. Also note that this SetPathInfo is preferred to
5473  * SetFileInfo based method in next routine which is only needed to work around
5474  * a sharing violation bugin Samba which this routine can run into.
5475  */
5476 int
CIFSSMBSetEOF(const unsigned int xid,struct cifs_tcon * tcon,const char * file_name,__u64 size,struct cifs_sb_info * cifs_sb,bool set_allocation,struct dentry * dentry)5477 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5478 	      const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5479 	      bool set_allocation, struct dentry *dentry)
5480 {
5481 	struct smb_com_transaction2_spi_req *pSMB = NULL;
5482 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5483 	struct file_end_of_file_info *parm_data;
5484 	unsigned int in_len;
5485 	int name_len;
5486 	int rc = 0;
5487 	int bytes_returned = 0;
5488 	int remap = cifs_remap(cifs_sb);
5489 
5490 	__u16 params, byte_count, data_count, param_offset, offset;
5491 
5492 	cifs_dbg(FYI, "In SetEOF\n");
5493 SetEOFRetry:
5494 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5495 		      (void **) &pSMBr);
5496 	if (rc < 0)
5497 		return rc;
5498 	in_len = rc;
5499 
5500 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5501 		name_len =
5502 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5503 				       PATH_MAX, cifs_sb->local_nls, remap);
5504 		name_len++;	/* trailing null */
5505 		name_len *= 2;
5506 	} else {
5507 		name_len = copy_path_name(pSMB->FileName, file_name);
5508 	}
5509 	params = 6 + name_len;
5510 	data_count = sizeof(struct file_end_of_file_info);
5511 	pSMB->MaxParameterCount = cpu_to_le16(2);
5512 	pSMB->MaxDataCount = cpu_to_le16(4100);
5513 	pSMB->MaxSetupCount = 0;
5514 	pSMB->Reserved = 0;
5515 	pSMB->Flags = 0;
5516 	pSMB->Timeout = 0;
5517 	pSMB->Reserved2 = 0;
5518 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5519 				InformationLevel);
5520 	offset = param_offset + params;
5521 	if (set_allocation) {
5522 		if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5523 			pSMB->InformationLevel =
5524 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5525 		else
5526 			pSMB->InformationLevel =
5527 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5528 	} else /* Set File Size */  {
5529 	    if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5530 		    pSMB->InformationLevel =
5531 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5532 	    else
5533 		    pSMB->InformationLevel =
5534 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5535 	}
5536 
5537 	parm_data =
5538 	    (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5539 				       offset);
5540 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5541 	pSMB->DataOffset = cpu_to_le16(offset);
5542 	pSMB->SetupCount = 1;
5543 	pSMB->Reserved3 = 0;
5544 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5545 	byte_count = 3 /* pad */  + params + data_count;
5546 	pSMB->DataCount = cpu_to_le16(data_count);
5547 	pSMB->TotalDataCount = pSMB->DataCount;
5548 	pSMB->ParameterCount = cpu_to_le16(params);
5549 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5550 	pSMB->Reserved4 = 0;
5551 	in_len += byte_count;
5552 	parm_data->FileSize = cpu_to_le64(size);
5553 	pSMB->ByteCount = cpu_to_le16(byte_count);
5554 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5555 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5556 	if (rc)
5557 		cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5558 
5559 	cifs_buf_release(pSMB);
5560 
5561 	if (rc == -EAGAIN)
5562 		goto SetEOFRetry;
5563 
5564 	return rc;
5565 }
5566 
5567 int
CIFSSMBSetFileSize(const unsigned int xid,struct cifs_tcon * tcon,struct cifsFileInfo * cfile,__u64 size,bool set_allocation)5568 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5569 		   struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5570 {
5571 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5572 	struct file_end_of_file_info *parm_data;
5573 	unsigned int in_len;
5574 	int rc = 0;
5575 	__u16 params, param_offset, offset, byte_count, count;
5576 
5577 	cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5578 		 (long long)size);
5579 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5580 	if (rc < 0)
5581 		return rc;
5582 	in_len = rc;
5583 
5584 	pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5585 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5586 
5587 	params = 6;
5588 	pSMB->MaxSetupCount = 0;
5589 	pSMB->Reserved = 0;
5590 	pSMB->Flags = 0;
5591 	pSMB->Timeout = 0;
5592 	pSMB->Reserved2 = 0;
5593 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
5594 	offset = param_offset + params;
5595 
5596 	count = sizeof(struct file_end_of_file_info);
5597 	pSMB->MaxParameterCount = cpu_to_le16(2);
5598 	/* BB find exact max SMB PDU from sess structure BB */
5599 	pSMB->MaxDataCount = cpu_to_le16(1000);
5600 	pSMB->SetupCount = 1;
5601 	pSMB->Reserved3 = 0;
5602 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5603 	byte_count = 3 /* pad */  + params + count;
5604 	pSMB->DataCount = cpu_to_le16(count);
5605 	pSMB->ParameterCount = cpu_to_le16(params);
5606 	pSMB->TotalDataCount = pSMB->DataCount;
5607 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5608 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5609 	parm_data =
5610 		(struct file_end_of_file_info *)(((char *)pSMB) + offset);
5611 	pSMB->DataOffset = cpu_to_le16(offset);
5612 	parm_data->FileSize = cpu_to_le64(size);
5613 	pSMB->Fid = cfile->fid.netfid;
5614 	if (set_allocation) {
5615 		if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5616 			pSMB->InformationLevel =
5617 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5618 		else
5619 			pSMB->InformationLevel =
5620 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5621 	} else /* Set File Size */  {
5622 	    if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5623 		    pSMB->InformationLevel =
5624 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5625 	    else
5626 		    pSMB->InformationLevel =
5627 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5628 	}
5629 	pSMB->Reserved4 = 0;
5630 	in_len += byte_count;
5631 	pSMB->ByteCount = cpu_to_le16(byte_count);
5632 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
5633 	cifs_small_buf_release(pSMB);
5634 	if (rc) {
5635 		cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5636 			 rc);
5637 	}
5638 
5639 	/* Note: On -EAGAIN error only caller can retry on handle based calls
5640 		since file handle passed in no longer valid */
5641 
5642 	return rc;
5643 }
5644 
5645 int
SMBSetInformation(const unsigned int xid,struct cifs_tcon * tcon,const char * fileName,__le32 attributes,__le64 write_time,const struct nls_table * nls_codepage,struct cifs_sb_info * cifs_sb)5646 SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon,
5647 		  const char *fileName, __le32 attributes, __le64 write_time,
5648 		  const struct nls_table *nls_codepage,
5649 		  struct cifs_sb_info *cifs_sb)
5650 {
5651 	SETATTR_REQ *pSMB;
5652 	SETATTR_RSP *pSMBr;
5653 	struct timespec64 ts;
5654 	unsigned int in_len;
5655 	int bytes_returned;
5656 	int name_len;
5657 	int rc;
5658 
5659 	cifs_dbg(FYI, "In %s path %s\n", __func__, fileName);
5660 
5661 retry:
5662 	rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5663 		      (void **) &pSMBr);
5664 	if (rc < 0)
5665 		return rc;
5666 	in_len = rc;
5667 
5668 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5669 		name_len =
5670 			cifsConvertToUTF16((__le16 *) pSMB->fileName,
5671 					   fileName, PATH_MAX, nls_codepage,
5672 					   cifs_remap(cifs_sb));
5673 		name_len++;     /* trailing null */
5674 		name_len *= 2;
5675 	} else {
5676 		name_len = copy_path_name(pSMB->fileName, fileName);
5677 	}
5678 	/* Only few attributes can be set by this command, others are not accepted by Win9x. */
5679 	pSMB->attr = cpu_to_le16(le32_to_cpu(attributes) &
5680 			(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE));
5681 	/* Zero write time value (in both NT and SETATTR formats) means to not change it. */
5682 	if (le64_to_cpu(write_time) != 0) {
5683 		ts = cifs_NTtimeToUnix(write_time);
5684 		pSMB->last_write_time = cpu_to_le32(ts.tv_sec);
5685 	}
5686 	pSMB->BufferFormat = 0x04;
5687 	name_len++; /* account for buffer type byte */
5688 	in_len += name_len;
5689 	pSMB->ByteCount = cpu_to_le16(name_len);
5690 
5691 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5692 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5693 	if (rc)
5694 		cifs_dbg(FYI, "Send error in %s = %d\n", __func__, rc);
5695 
5696 	cifs_buf_release(pSMB);
5697 
5698 	if (rc == -EAGAIN)
5699 		goto retry;
5700 
5701 	return rc;
5702 }
5703 
5704 /* Some legacy servers such as NT4 require that the file times be set on
5705    an open handle, rather than by pathname - this is awkward due to
5706    potential access conflicts on the open, but it is unavoidable for these
5707    old servers since the only other choice is to go from 100 nanosecond DCE
5708    time and resort to the original setpathinfo level which takes the ancient
5709    DOS time format with 2 second granularity */
5710 int
CIFSSMBSetFileInfo(const unsigned int xid,struct cifs_tcon * tcon,const FILE_BASIC_INFO * data,__u16 fid,__u32 pid_of_opener)5711 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5712 		    const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5713 {
5714 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5715 	unsigned int in_len;
5716 	char *data_offset;
5717 	int rc = 0;
5718 	__u16 params, param_offset, offset, byte_count, count;
5719 
5720 	cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5721 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5722 	if (rc < 0)
5723 		return rc;
5724 	in_len = rc;
5725 
5726 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5727 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5728 
5729 	params = 6;
5730 	pSMB->MaxSetupCount = 0;
5731 	pSMB->Reserved = 0;
5732 	pSMB->Flags = 0;
5733 	pSMB->Timeout = 0;
5734 	pSMB->Reserved2 = 0;
5735 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
5736 	offset = param_offset + params;
5737 
5738 	data_offset = (char *)pSMB + offset;
5739 
5740 	count = sizeof(FILE_BASIC_INFO);
5741 	pSMB->MaxParameterCount = cpu_to_le16(2);
5742 	/* BB find max SMB PDU from sess */
5743 	pSMB->MaxDataCount = cpu_to_le16(1000);
5744 	pSMB->SetupCount = 1;
5745 	pSMB->Reserved3 = 0;
5746 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5747 	byte_count = 3 /* pad */  + params + count;
5748 	pSMB->DataCount = cpu_to_le16(count);
5749 	pSMB->ParameterCount = cpu_to_le16(params);
5750 	pSMB->TotalDataCount = pSMB->DataCount;
5751 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5752 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5753 	pSMB->DataOffset = cpu_to_le16(offset);
5754 	pSMB->Fid = fid;
5755 	if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5756 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5757 	else
5758 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5759 	pSMB->Reserved4 = 0;
5760 	in_len += byte_count;
5761 	pSMB->ByteCount = cpu_to_le16(byte_count);
5762 	memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5763 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
5764 	cifs_small_buf_release(pSMB);
5765 	if (rc)
5766 		cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5767 			 rc);
5768 
5769 	/* Note: On -EAGAIN error only caller can retry on handle based calls
5770 		since file handle passed in no longer valid */
5771 
5772 	return rc;
5773 }
5774 
5775 int
CIFSSMBSetFileDisposition(const unsigned int xid,struct cifs_tcon * tcon,bool delete_file,__u16 fid,__u32 pid_of_opener)5776 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5777 			  bool delete_file, __u16 fid, __u32 pid_of_opener)
5778 {
5779 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5780 	unsigned int in_len;
5781 	char *data_offset;
5782 	int rc = 0;
5783 	__u16 params, param_offset, offset, byte_count, count;
5784 
5785 	cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5786 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5787 	if (rc < 0)
5788 		return rc;
5789 	in_len = rc;
5790 
5791 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5792 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5793 
5794 	params = 6;
5795 	pSMB->MaxSetupCount = 0;
5796 	pSMB->Reserved = 0;
5797 	pSMB->Flags = 0;
5798 	pSMB->Timeout = 0;
5799 	pSMB->Reserved2 = 0;
5800 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
5801 	offset = param_offset + params;
5802 	data_offset = (char *)(pSMB) + offset;
5803 
5804 	count = 1;
5805 	pSMB->MaxParameterCount = cpu_to_le16(2);
5806 	/* BB find max SMB PDU from sess */
5807 	pSMB->MaxDataCount = cpu_to_le16(1000);
5808 	pSMB->SetupCount = 1;
5809 	pSMB->Reserved3 = 0;
5810 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5811 	byte_count = 3 /* pad */  + params + count;
5812 	pSMB->DataCount = cpu_to_le16(count);
5813 	pSMB->ParameterCount = cpu_to_le16(params);
5814 	pSMB->TotalDataCount = pSMB->DataCount;
5815 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5816 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5817 	pSMB->DataOffset = cpu_to_le16(offset);
5818 	pSMB->Fid = fid;
5819 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5820 	pSMB->Reserved4 = 0;
5821 	in_len += byte_count;
5822 	pSMB->ByteCount = cpu_to_le16(byte_count);
5823 	*data_offset = delete_file ? 1 : 0;
5824 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
5825 	cifs_small_buf_release(pSMB);
5826 	if (rc)
5827 		cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5828 
5829 	return rc;
5830 }
5831 
5832 static int
CIFSSMBSetPathInfoFB(const unsigned int xid,struct cifs_tcon * tcon,const char * fileName,const FILE_BASIC_INFO * data,const struct nls_table * nls_codepage,struct cifs_sb_info * cifs_sb)5833 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5834 		     const char *fileName, const FILE_BASIC_INFO *data,
5835 		     const struct nls_table *nls_codepage,
5836 		     struct cifs_sb_info *cifs_sb)
5837 {
5838 	int oplock = 0;
5839 	struct cifs_open_parms oparms;
5840 	struct cifs_fid fid;
5841 	int rc;
5842 
5843 	oparms = (struct cifs_open_parms) {
5844 		.tcon = tcon,
5845 		.cifs_sb = cifs_sb,
5846 		.desired_access = GENERIC_WRITE,
5847 		.create_options = cifs_create_options(cifs_sb, 0),
5848 		.disposition = FILE_OPEN,
5849 		.path = fileName,
5850 		.fid = &fid,
5851 	};
5852 
5853 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
5854 	if (rc)
5855 		goto out;
5856 
5857 	rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5858 	CIFSSMBClose(xid, tcon, fid.netfid);
5859 out:
5860 
5861 	return rc;
5862 }
5863 
5864 int
CIFSSMBSetPathInfo(const unsigned int xid,struct cifs_tcon * tcon,const char * fileName,const FILE_BASIC_INFO * data,const struct nls_table * nls_codepage,struct cifs_sb_info * cifs_sb)5865 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5866 		   const char *fileName, const FILE_BASIC_INFO *data,
5867 		   const struct nls_table *nls_codepage,
5868 		     struct cifs_sb_info *cifs_sb)
5869 {
5870 	TRANSACTION2_SPI_REQ *pSMB = NULL;
5871 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
5872 	unsigned int in_len;
5873 	int name_len;
5874 	int rc = 0;
5875 	int bytes_returned = 0;
5876 	char *data_offset;
5877 	__u16 params, param_offset, offset, byte_count, count;
5878 	int remap = cifs_remap(cifs_sb);
5879 
5880 	cifs_dbg(FYI, "In SetTimes\n");
5881 
5882 SetTimesRetry:
5883 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5884 		      (void **) &pSMBr);
5885 	if (rc < 0)
5886 		return rc;
5887 	in_len = rc;
5888 
5889 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5890 		name_len =
5891 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5892 				       PATH_MAX, nls_codepage, remap);
5893 		name_len++;	/* trailing null */
5894 		name_len *= 2;
5895 	} else {
5896 		name_len = copy_path_name(pSMB->FileName, fileName);
5897 	}
5898 
5899 	params = 6 + name_len;
5900 	count = sizeof(FILE_BASIC_INFO);
5901 	pSMB->MaxParameterCount = cpu_to_le16(2);
5902 	/* BB find max SMB PDU from sess structure BB */
5903 	pSMB->MaxDataCount = cpu_to_le16(1000);
5904 	pSMB->MaxSetupCount = 0;
5905 	pSMB->Reserved = 0;
5906 	pSMB->Flags = 0;
5907 	pSMB->Timeout = 0;
5908 	pSMB->Reserved2 = 0;
5909 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5910 				InformationLevel);
5911 	offset = param_offset + params;
5912 	data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset;
5913 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5914 	pSMB->DataOffset = cpu_to_le16(offset);
5915 	pSMB->SetupCount = 1;
5916 	pSMB->Reserved3 = 0;
5917 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5918 	byte_count = 3 /* pad */  + params + count;
5919 
5920 	pSMB->DataCount = cpu_to_le16(count);
5921 	pSMB->ParameterCount = cpu_to_le16(params);
5922 	pSMB->TotalDataCount = pSMB->DataCount;
5923 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5924 	if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5925 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5926 	else
5927 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5928 	pSMB->Reserved4 = 0;
5929 	in_len += byte_count;
5930 	memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5931 	pSMB->ByteCount = cpu_to_le16(byte_count);
5932 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5933 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5934 	if (rc)
5935 		cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5936 
5937 	cifs_buf_release(pSMB);
5938 
5939 	if (rc == -EAGAIN)
5940 		goto SetTimesRetry;
5941 
5942 	if (rc == -EOPNOTSUPP)
5943 		return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5944 					    nls_codepage, cifs_sb);
5945 
5946 	return rc;
5947 }
5948 
5949 static void
cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO * data_offset,const struct cifs_unix_set_info_args * args)5950 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5951 			const struct cifs_unix_set_info_args *args)
5952 {
5953 	u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5954 	u64 mode = args->mode;
5955 
5956 	if (uid_valid(args->uid))
5957 		uid = from_kuid(&init_user_ns, args->uid);
5958 	if (gid_valid(args->gid))
5959 		gid = from_kgid(&init_user_ns, args->gid);
5960 
5961 	/*
5962 	 * Samba server ignores set of file size to zero due to bugs in some
5963 	 * older clients, but we should be precise - we use SetFileSize to
5964 	 * set file size and do not want to truncate file size to zero
5965 	 * accidentally as happened on one Samba server beta by putting
5966 	 * zero instead of -1 here
5967 	 */
5968 	data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5969 	data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5970 	data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5971 	data_offset->LastAccessTime = cpu_to_le64(args->atime);
5972 	data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5973 	data_offset->Uid = cpu_to_le64(uid);
5974 	data_offset->Gid = cpu_to_le64(gid);
5975 	/* better to leave device as zero when it is  */
5976 	data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5977 	data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5978 	data_offset->Permissions = cpu_to_le64(mode);
5979 
5980 	if (S_ISREG(mode))
5981 		data_offset->Type = cpu_to_le32(UNIX_FILE);
5982 	else if (S_ISDIR(mode))
5983 		data_offset->Type = cpu_to_le32(UNIX_DIR);
5984 	else if (S_ISLNK(mode))
5985 		data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5986 	else if (S_ISCHR(mode))
5987 		data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5988 	else if (S_ISBLK(mode))
5989 		data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5990 	else if (S_ISFIFO(mode))
5991 		data_offset->Type = cpu_to_le32(UNIX_FIFO);
5992 	else if (S_ISSOCK(mode))
5993 		data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5994 }
5995 
5996 int
CIFSSMBUnixSetFileInfo(const unsigned int xid,struct cifs_tcon * tcon,const struct cifs_unix_set_info_args * args,u16 fid,u32 pid_of_opener)5997 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5998 		       const struct cifs_unix_set_info_args *args,
5999 		       u16 fid, u32 pid_of_opener)
6000 {
6001 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
6002 	unsigned int in_len;
6003 	char *data_offset;
6004 	int rc = 0;
6005 	u16 params, param_offset, offset, byte_count, count;
6006 
6007 	cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
6008 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6009 	if (rc < 0)
6010 		return rc;
6011 	in_len = rc;
6012 
6013 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6014 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6015 
6016 	params = 6;
6017 	pSMB->MaxSetupCount = 0;
6018 	pSMB->Reserved = 0;
6019 	pSMB->Flags = 0;
6020 	pSMB->Timeout = 0;
6021 	pSMB->Reserved2 = 0;
6022 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
6023 	offset = param_offset + params;
6024 
6025 	data_offset = (char *)pSMB + offset;
6026 
6027 	count = sizeof(FILE_UNIX_BASIC_INFO);
6028 
6029 	pSMB->MaxParameterCount = cpu_to_le16(2);
6030 	/* BB find max SMB PDU from sess */
6031 	pSMB->MaxDataCount = cpu_to_le16(1000);
6032 	pSMB->SetupCount = 1;
6033 	pSMB->Reserved3 = 0;
6034 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6035 	byte_count = 3 /* pad */  + params + count;
6036 	pSMB->DataCount = cpu_to_le16(count);
6037 	pSMB->ParameterCount = cpu_to_le16(params);
6038 	pSMB->TotalDataCount = pSMB->DataCount;
6039 	pSMB->TotalParameterCount = pSMB->ParameterCount;
6040 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
6041 	pSMB->DataOffset = cpu_to_le16(offset);
6042 	pSMB->Fid = fid;
6043 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6044 	pSMB->Reserved4 = 0;
6045 	in_len += byte_count;
6046 	pSMB->ByteCount = cpu_to_le16(byte_count);
6047 
6048 	cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6049 
6050 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
6051 	cifs_small_buf_release(pSMB);
6052 	if (rc)
6053 		cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6054 			 rc);
6055 
6056 	/* Note: On -EAGAIN error only caller can retry on handle based calls
6057 		since file handle passed in no longer valid */
6058 
6059 	return rc;
6060 }
6061 
6062 int
CIFSSMBUnixSetPathInfo(const unsigned int xid,struct cifs_tcon * tcon,const char * file_name,const struct cifs_unix_set_info_args * args,const struct nls_table * nls_codepage,int remap)6063 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6064 		       const char *file_name,
6065 		       const struct cifs_unix_set_info_args *args,
6066 		       const struct nls_table *nls_codepage, int remap)
6067 {
6068 	TRANSACTION2_SPI_REQ *pSMB = NULL;
6069 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
6070 	unsigned int in_len;
6071 	int name_len;
6072 	int rc = 0;
6073 	int bytes_returned = 0;
6074 	FILE_UNIX_BASIC_INFO *data_offset;
6075 	__u16 params, param_offset, offset, count, byte_count;
6076 
6077 	cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6078 setPermsRetry:
6079 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6080 		      (void **) &pSMBr);
6081 	if (rc < 0)
6082 		return rc;
6083 	in_len = rc;
6084 
6085 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6086 		name_len =
6087 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6088 				       PATH_MAX, nls_codepage, remap);
6089 		name_len++;	/* trailing null */
6090 		name_len *= 2;
6091 	} else {
6092 		name_len = copy_path_name(pSMB->FileName, file_name);
6093 	}
6094 
6095 	params = 6 + name_len;
6096 	count = sizeof(FILE_UNIX_BASIC_INFO);
6097 	pSMB->MaxParameterCount = cpu_to_le16(2);
6098 	/* BB find max SMB PDU from sess structure BB */
6099 	pSMB->MaxDataCount = cpu_to_le16(1000);
6100 	pSMB->MaxSetupCount = 0;
6101 	pSMB->Reserved = 0;
6102 	pSMB->Flags = 0;
6103 	pSMB->Timeout = 0;
6104 	pSMB->Reserved2 = 0;
6105 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
6106 				InformationLevel);
6107 	offset = param_offset + params;
6108 	data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset);
6109 	memset(data_offset, 0, count);
6110 	pSMB->DataOffset = cpu_to_le16(offset);
6111 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
6112 	pSMB->SetupCount = 1;
6113 	pSMB->Reserved3 = 0;
6114 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6115 	byte_count = 3 /* pad */  + params + count;
6116 	pSMB->ParameterCount = cpu_to_le16(params);
6117 	pSMB->DataCount = cpu_to_le16(count);
6118 	pSMB->TotalParameterCount = pSMB->ParameterCount;
6119 	pSMB->TotalDataCount = pSMB->DataCount;
6120 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6121 	pSMB->Reserved4 = 0;
6122 	in_len += byte_count;
6123 
6124 	cifs_fill_unix_set_info(data_offset, args);
6125 
6126 	pSMB->ByteCount = cpu_to_le16(byte_count);
6127 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
6128 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6129 	if (rc)
6130 		cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6131 
6132 	cifs_buf_release(pSMB);
6133 	if (rc == -EAGAIN)
6134 		goto setPermsRetry;
6135 	return rc;
6136 }
6137 
6138 #ifdef CONFIG_CIFS_XATTR
6139 /*
6140  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6141  * function used by listxattr and getxattr type calls. When ea_name is set,
6142  * it looks for that attribute name and stuffs that value into the EAData
6143  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6144  * buffer. In both cases, the return value is either the length of the
6145  * resulting data or a negative error code. If EAData is a NULL pointer then
6146  * the data isn't copied to it, but the length is returned.
6147  */
6148 ssize_t
CIFSSMBQAllEAs(const unsigned int xid,struct cifs_tcon * tcon,const unsigned char * searchName,const unsigned char * ea_name,char * EAData,size_t buf_size,struct cifs_sb_info * cifs_sb)6149 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6150 		const unsigned char *searchName, const unsigned char *ea_name,
6151 		char *EAData, size_t buf_size,
6152 		struct cifs_sb_info *cifs_sb)
6153 {
6154 		/* BB assumes one setup word */
6155 	TRANSACTION2_QPI_REQ *pSMB = NULL;
6156 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
6157 	int remap = cifs_remap(cifs_sb);
6158 	struct nls_table *nls_codepage = cifs_sb->local_nls;
6159 	unsigned int in_len;
6160 	int rc = 0;
6161 	int bytes_returned;
6162 	int list_len;
6163 	struct fealist *ea_response_data;
6164 	struct fea *temp_fea;
6165 	char *temp_ptr;
6166 	char *end_of_smb;
6167 	__u16 params, byte_count, data_offset;
6168 	unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6169 
6170 	cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6171 QAllEAsRetry:
6172 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6173 		      (void **) &pSMBr);
6174 	if (rc < 0)
6175 		return rc;
6176 	in_len = rc;
6177 
6178 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6179 		list_len =
6180 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6181 				       PATH_MAX, nls_codepage, remap);
6182 		list_len++;	/* trailing null */
6183 		list_len *= 2;
6184 	} else {
6185 		list_len = copy_path_name(pSMB->FileName, searchName);
6186 	}
6187 
6188 	params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6189 	pSMB->TotalDataCount = 0;
6190 	pSMB->MaxParameterCount = cpu_to_le16(2);
6191 	/* BB find exact max SMB PDU from sess structure BB */
6192 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6193 	pSMB->MaxSetupCount = 0;
6194 	pSMB->Reserved = 0;
6195 	pSMB->Flags = 0;
6196 	pSMB->Timeout = 0;
6197 	pSMB->Reserved2 = 0;
6198 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
6199 		struct smb_com_transaction2_qpi_req, InformationLevel));
6200 	pSMB->DataCount = 0;
6201 	pSMB->DataOffset = 0;
6202 	pSMB->SetupCount = 1;
6203 	pSMB->Reserved3 = 0;
6204 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6205 	byte_count = params + 1 /* pad */ ;
6206 	pSMB->TotalParameterCount = cpu_to_le16(params);
6207 	pSMB->ParameterCount = pSMB->TotalParameterCount;
6208 	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6209 	pSMB->Reserved4 = 0;
6210 	in_len += byte_count;
6211 	pSMB->ByteCount = cpu_to_le16(byte_count);
6212 
6213 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
6214 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6215 	if (rc) {
6216 		cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6217 		goto QAllEAsOut;
6218 	}
6219 
6220 
6221 	/* BB also check enough total bytes returned */
6222 	/* BB we need to improve the validity checking
6223 	of these trans2 responses */
6224 
6225 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6226 	if (rc || get_bcc(&pSMBr->hdr) < 4) {
6227 		rc = smb_EIO2(smb_eio_trace_qalleas_bcc_too_small,
6228 			      get_bcc(&pSMBr->hdr), 4);
6229 		goto QAllEAsOut;
6230 	}
6231 
6232 	/* check that length of list is not more than bcc */
6233 	/* check that each entry does not go beyond length
6234 	   of list */
6235 	/* check that each element of each entry does not
6236 	   go beyond end of list */
6237 	/* validate_trans2_offsets() */
6238 	/* BB check if start of smb + data_offset > &bcc+ bcc */
6239 
6240 	data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6241 	ea_response_data = (struct fealist *)
6242 				(((char *) &pSMBr->hdr.Protocol) + data_offset);
6243 
6244 	list_len = le32_to_cpu(ea_response_data->list_len);
6245 	cifs_dbg(FYI, "ea length %d\n", list_len);
6246 	if (list_len <= 8) {
6247 		cifs_dbg(FYI, "empty EA list returned from server\n");
6248 		/* didn't find the named attribute */
6249 		if (ea_name)
6250 			rc = -ENODATA;
6251 		goto QAllEAsOut;
6252 	}
6253 
6254 	/* make sure list_len doesn't go past end of SMB */
6255 	end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6256 	if ((char *)ea_response_data + list_len > end_of_smb) {
6257 		cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6258 		rc = smb_EIO2(smb_eio_trace_qalleas_overlong,
6259 			      (unsigned long)ea_response_data + list_len - (unsigned long)pSMBr,
6260 			      (unsigned long)end_of_smb - (unsigned long)pSMBr);
6261 		goto QAllEAsOut;
6262 	}
6263 
6264 	/* account for ea list len */
6265 	list_len -= 4;
6266 	temp_fea = &ea_response_data->list;
6267 	temp_ptr = (char *)temp_fea;
6268 	while (list_len > 0) {
6269 		unsigned int name_len;
6270 		__u16 value_len;
6271 
6272 		list_len -= 4;
6273 		temp_ptr += 4;
6274 		/* make sure we can read name_len and value_len */
6275 		if (list_len < 0) {
6276 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6277 			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
6278 			goto QAllEAsOut;
6279 		}
6280 
6281 		name_len = temp_fea->name_len;
6282 		value_len = le16_to_cpu(temp_fea->value_len);
6283 		list_len -= name_len + 1 + value_len;
6284 		if (list_len < 0) {
6285 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6286 			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
6287 			goto QAllEAsOut;
6288 		}
6289 
6290 		if (ea_name) {
6291 			if (ea_name_len == name_len &&
6292 			    memcmp(ea_name, temp_ptr, name_len) == 0) {
6293 				temp_ptr += name_len + 1;
6294 				rc = value_len;
6295 				if (buf_size == 0)
6296 					goto QAllEAsOut;
6297 				if ((size_t)value_len > buf_size) {
6298 					rc = -ERANGE;
6299 					goto QAllEAsOut;
6300 				}
6301 				memcpy(EAData, temp_ptr, value_len);
6302 				goto QAllEAsOut;
6303 			}
6304 		} else {
6305 			/* account for prefix user. and trailing null */
6306 			rc += (5 + 1 + name_len);
6307 			if (rc < (int) buf_size) {
6308 				memcpy(EAData, "user.", 5);
6309 				EAData += 5;
6310 				memcpy(EAData, temp_ptr, name_len);
6311 				EAData += name_len;
6312 				/* null terminate name */
6313 				*EAData = 0;
6314 				++EAData;
6315 			} else if (buf_size == 0) {
6316 				/* skip copy - calc size only */
6317 			} else {
6318 				/* stop before overrun buffer */
6319 				rc = -ERANGE;
6320 				break;
6321 			}
6322 		}
6323 		temp_ptr += name_len + 1 + value_len;
6324 		temp_fea = (struct fea *)temp_ptr;
6325 	}
6326 
6327 	/* didn't find the named attribute */
6328 	if (ea_name)
6329 		rc = -ENODATA;
6330 
6331 QAllEAsOut:
6332 	cifs_buf_release(pSMB);
6333 	if (rc == -EAGAIN)
6334 		goto QAllEAsRetry;
6335 
6336 	return (ssize_t)rc;
6337 }
6338 
6339 int
CIFSSMBSetEA(const unsigned int xid,struct cifs_tcon * tcon,const char * fileName,const char * ea_name,const void * ea_value,const __u16 ea_value_len,const struct nls_table * nls_codepage,struct cifs_sb_info * cifs_sb)6340 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6341 	     const char *fileName, const char *ea_name, const void *ea_value,
6342 	     const __u16 ea_value_len, const struct nls_table *nls_codepage,
6343 	     struct cifs_sb_info *cifs_sb)
6344 {
6345 	struct smb_com_transaction2_spi_req *pSMB = NULL;
6346 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6347 	struct fealist *parm_data;
6348 	unsigned int in_len;
6349 	int name_len;
6350 	int rc = 0;
6351 	int bytes_returned = 0;
6352 	__u16 params, param_offset, byte_count, offset, count;
6353 	int remap = cifs_remap(cifs_sb);
6354 
6355 	cifs_dbg(FYI, "In SetEA\n");
6356 SetEARetry:
6357 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6358 		      (void **) &pSMBr);
6359 	if (rc < 0)
6360 		return rc;
6361 	in_len = rc;
6362 
6363 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6364 		name_len =
6365 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6366 				       PATH_MAX, nls_codepage, remap);
6367 		name_len++;	/* trailing null */
6368 		name_len *= 2;
6369 	} else {
6370 		name_len = copy_path_name(pSMB->FileName, fileName);
6371 	}
6372 
6373 	params = 6 + name_len;
6374 
6375 	/* done calculating parms using name_len of file name,
6376 	now use name_len to calculate length of ea name
6377 	we are going to create in the inode xattrs */
6378 	if (ea_name == NULL)
6379 		name_len = 0;
6380 	else
6381 		name_len = strnlen(ea_name, 255);
6382 
6383 	count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
6384 	pSMB->MaxParameterCount = cpu_to_le16(2);
6385 	/* BB find max SMB PDU from sess */
6386 	pSMB->MaxDataCount = cpu_to_le16(1000);
6387 	pSMB->MaxSetupCount = 0;
6388 	pSMB->Reserved = 0;
6389 	pSMB->Flags = 0;
6390 	pSMB->Timeout = 0;
6391 	pSMB->Reserved2 = 0;
6392 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
6393 				InformationLevel);
6394 	offset = param_offset + params;
6395 	pSMB->InformationLevel =
6396 		cpu_to_le16(SMB_SET_FILE_EA);
6397 
6398 	parm_data = (void *)pSMB + offset;
6399 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
6400 	pSMB->DataOffset = cpu_to_le16(offset);
6401 	pSMB->SetupCount = 1;
6402 	pSMB->Reserved3 = 0;
6403 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6404 	byte_count = 3 /* pad */  + params + count;
6405 	pSMB->DataCount = cpu_to_le16(count);
6406 	parm_data->list_len = cpu_to_le32(count);
6407 	parm_data->list.EA_flags = 0;
6408 	/* we checked above that name len is less than 255 */
6409 	parm_data->list.name_len = (__u8)name_len;
6410 	/* EA names are always ASCII and NUL-terminated */
6411 	strscpy(parm_data->list.name, ea_name ?: "", name_len + 1);
6412 	parm_data->list.value_len = cpu_to_le16(ea_value_len);
6413 	/* caller ensures that ea_value_len is less than 64K but
6414 	we need to ensure that it fits within the smb */
6415 
6416 	/*BB add length check to see if it would fit in
6417 	     negotiated SMB buffer size BB */
6418 	/* if (ea_value_len > buffer_size - 512 (enough for header)) */
6419 	if (ea_value_len)
6420 		memcpy(parm_data->list.name + name_len + 1,
6421 		       ea_value, ea_value_len);
6422 
6423 	pSMB->TotalDataCount = pSMB->DataCount;
6424 	pSMB->ParameterCount = cpu_to_le16(params);
6425 	pSMB->TotalParameterCount = pSMB->ParameterCount;
6426 	pSMB->Reserved4 = 0;
6427 	in_len += byte_count;
6428 	pSMB->ByteCount = cpu_to_le16(byte_count);
6429 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
6430 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6431 	if (rc)
6432 		cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6433 
6434 	cifs_buf_release(pSMB);
6435 
6436 	if (rc == -EAGAIN)
6437 		goto SetEARetry;
6438 
6439 	return rc;
6440 }
6441 #endif
6442