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