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