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