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