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