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