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