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