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