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