1 /*
2  *  proc.c
3  *
4  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5  *  Copyright (C) 1997 by Volker Lendecke
6  *
7  *  Please add a note about your changes to smbfs in the ChangeLog file.
8  */
9 
10 #include <linux/types.h>
11 #include <linux/errno.h>
12 #include <linux/slab.h>
13 #include <linux/fs.h>
14 #include <linux/file.h>
15 #include <linux/stat.h>
16 #include <linux/fcntl.h>
17 #include <linux/dcache.h>
18 #include <linux/dirent.h>
19 #include <linux/nls.h>
20 
21 #include <linux/smb_fs.h>
22 #include <linux/smbno.h>
23 #include <linux/smb_mount.h>
24 
25 #include <asm/string.h>
26 #include <asm/div64.h>
27 
28 #include "smb_debug.h"
29 #include "proto.h"
30 
31 
32 /* Features. Undefine if they cause problems, this should perhaps be a
33    config option. */
34 #define SMBFS_POSIX_UNLINK 1
35 
36 #define SMB_VWV(packet)  ((packet) + SMB_HEADER_LEN)
37 #define SMB_CMD(packet)  (*(packet+8))
38 #define SMB_WCT(packet)  (*(packet+SMB_HEADER_LEN - 1))
39 #define SMB_BCC(packet)  smb_bcc(packet)
40 #define SMB_BUF(packet)  ((packet) + SMB_HEADER_LEN + SMB_WCT(packet) * 2 + 2)
41 
42 #define SMB_DIRINFO_SIZE 43
43 #define SMB_STATUS_SIZE  21
44 
45 #define SMB_ST_BLKSIZE	(PAGE_SIZE)
46 #define SMB_ST_BLKSHIFT	(PAGE_SHIFT)
47 
48 static struct smb_ops smb_ops_core;
49 static struct smb_ops smb_ops_os2;
50 static struct smb_ops smb_ops_win95;
51 static struct smb_ops smb_ops_winNT;
52 static struct smb_ops smb_ops_unix;
53 
54 static void
55 smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
56 static void
57 smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
58 static int
59 smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
60 		      struct smb_fattr *fattr);
61 static int
62 smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dir,
63 		    struct smb_fattr *fattr);
64 static int
65 smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
66 		     struct smb_fattr *);
67 static int
68 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
69                       __u16 attr);
70 static void
71 install_ops(struct smb_ops *dst, struct smb_ops *src);
72 static int
73 smb_proc_query_cifsunix(struct smb_sb_info *server);
74 
75 
76 static void
str_upper(char * name,int len)77 str_upper(char *name, int len)
78 {
79 	while (len--)
80 	{
81 		if (*name >= 'a' && *name <= 'z')
82 			*name -= ('a' - 'A');
83 		name++;
84 	}
85 }
86 
87 #if 0
88 static void
89 str_lower(char *name, int len)
90 {
91 	while (len--)
92 	{
93 		if (*name >= 'A' && *name <= 'Z')
94 			*name += ('a' - 'A');
95 		name++;
96 	}
97 }
98 #endif
99 
100 /* reverse a string inline. This is used by the dircache walking routines */
reverse_string(char * buf,int len)101 static void reverse_string(char *buf, int len)
102 {
103 	char c;
104 	char *end = buf+len-1;
105 
106 	while(buf < end) {
107 		c = *buf;
108 		*(buf++) = *end;
109 		*(end--) = c;
110 	}
111 }
112 
113 /* no conversion, just a wrapper for memcpy. */
convert_memcpy(unsigned char * output,int olen,const unsigned char * input,int ilen,struct nls_table * nls_from,struct nls_table * nls_to)114 static int convert_memcpy(unsigned char *output, int olen,
115 			  const unsigned char *input, int ilen,
116 			  struct nls_table *nls_from,
117 			  struct nls_table *nls_to)
118 {
119 	if (olen < ilen)
120 		return -ENAMETOOLONG;
121 	memcpy(output, input, ilen);
122 	return ilen;
123 }
124 
write_char(unsigned char ch,char * output,int olen)125 static inline int write_char(unsigned char ch, char *output, int olen)
126 {
127 	if (olen < 4)
128 		return -ENAMETOOLONG;
129 	sprintf(output, ":x%02x", ch);
130 	return 4;
131 }
132 
write_unichar(wchar_t ch,char * output,int olen)133 static inline int write_unichar(wchar_t ch, char *output, int olen)
134 {
135 	if (olen < 5)
136 		return -ENAMETOOLONG;
137 	sprintf(output, ":%04x", ch);
138 	return 5;
139 }
140 
141 /* convert from one "codepage" to another (possibly being utf8). */
convert_cp(unsigned char * output,int olen,const unsigned char * input,int ilen,struct nls_table * nls_from,struct nls_table * nls_to)142 static int convert_cp(unsigned char *output, int olen,
143 		      const unsigned char *input, int ilen,
144 		      struct nls_table *nls_from,
145 		      struct nls_table *nls_to)
146 {
147 	int len = 0;
148 	int n;
149 	wchar_t ch;
150 
151 	while (ilen > 0) {
152 		/* convert by changing to unicode and back to the new cp */
153 		n = nls_from->char2uni((unsigned char *)input, ilen, &ch);
154 		if (n == -EINVAL) {
155 			ilen--;
156 			n = write_char(*input++, output, olen);
157 			if (n < 0)
158 				goto fail;
159 			output += n;
160 			olen -= n;
161 			len += n;
162 			continue;
163 		} else if (n < 0)
164 			goto fail;
165 		input += n;
166 		ilen -= n;
167 
168 		n = nls_to->uni2char(ch, output, olen);
169 		if (n == -EINVAL)
170 			n = write_unichar(ch, output, olen);
171 		if (n < 0)
172 			goto fail;
173 		output += n;
174 		olen -= n;
175 
176 		len += n;
177 	}
178 	return len;
179 fail:
180 	return n;
181 }
182 
setcodepage(struct nls_table ** p,char * name)183 static int setcodepage(struct nls_table **p, char *name)
184 {
185 	struct nls_table *nls;
186 
187 	if (!name || !*name) {
188 		nls = NULL;
189 	} else if ( (nls = load_nls(name)) == NULL) {
190 		printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name);
191 		return -EINVAL;
192 	}
193 
194 	/* if already set, unload the previous one. */
195 	if (*p)
196 		unload_nls(*p);
197 	*p = nls;
198 
199 	return 0;
200 }
201 
202 /* Handles all changes to codepage settings. */
smb_setcodepage(struct smb_sb_info * server,struct smb_nls_codepage * cp)203 int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp)
204 {
205 	int n = 0;
206 
207 	smb_lock_server(server);
208 
209 	/* Don't load any nls_* at all, if no remote is requested */
210 	if (!*cp->remote_name)
211 		goto out;
212 
213 	n = setcodepage(&server->local_nls, cp->local_name);
214 	if (n != 0)
215 		goto out;
216 	n = setcodepage(&server->remote_nls, cp->remote_name);
217 	if (n != 0)
218 		setcodepage(&server->local_nls, NULL);
219 
220 out:
221 	if (server->local_nls != NULL && server->remote_nls != NULL)
222 		server->ops->convert = convert_cp;
223 	else
224 		server->ops->convert = convert_memcpy;
225 
226 	smb_unlock_server(server);
227 	return n;
228 }
229 
230 
231 /*****************************************************************************/
232 /*                                                                           */
233 /*  Encoding/Decoding section                                                */
234 /*                                                                           */
235 /*****************************************************************************/
236 
237 static __u8 *
smb_encode_smb_length(__u8 * p,__u32 len)238 smb_encode_smb_length(__u8 * p, __u32 len)
239 {
240 	*p = 0;
241 	*(p+1) = 0;
242 	*(p+2) = (len & 0xFF00) >> 8;
243 	*(p+3) = (len & 0xFF);
244 	if (len > 0xFFFF)
245 	{
246 		*(p+1) = 1;
247 	}
248 	return p + 4;
249 }
250 
251 /*
252  * smb_build_path: build the path to entry and name storing it in buf.
253  * The path returned will have the trailing '\0'.
254  */
smb_build_path(struct smb_sb_info * server,char * buf,int maxlen,struct dentry * entry,struct qstr * name)255 static int smb_build_path(struct smb_sb_info *server, char * buf, int maxlen,
256 			  struct dentry * entry, struct qstr * name)
257 {
258 	char *path = buf;
259 	int len;
260 
261 	if (maxlen < 2)
262 		return -ENAMETOOLONG;
263 
264 	if (maxlen > SMB_MAXPATHLEN + 1)
265 		maxlen = SMB_MAXPATHLEN + 1;
266 
267 	if (entry == NULL)
268 		goto test_name_and_out;
269 
270 	/*
271 	 * If IS_ROOT, we have to do no walking at all.
272 	 */
273 	if (IS_ROOT(entry) && !name) {
274 		*path++ = '\\';
275 		*path++ = '\0';
276 		return 2;
277 	}
278 
279 	/*
280 	 * Build the path string walking the tree backward from end to ROOT
281 	 * and store it in reversed order [see reverse_string()]
282 	 */
283 	while (!IS_ROOT(entry)) {
284 		if (maxlen < 3)
285 			return -ENAMETOOLONG;
286 
287 		len = server->ops->convert(path, maxlen-2,
288 				      entry->d_name.name, entry->d_name.len,
289 				      server->local_nls, server->remote_nls);
290 		if (len < 0)
291 			return len;
292 		reverse_string(path, len);
293 		path += len;
294 		*path++ = '\\';
295 		maxlen -= len+1;
296 
297 		entry = entry->d_parent;
298 		if (IS_ROOT(entry))
299 			break;
300 	}
301 	reverse_string(buf, path-buf);
302 
303 	/* maxlen is at least 1 */
304 test_name_and_out:
305 	if (name) {
306 		if (maxlen < 3)
307 			return -ENAMETOOLONG;
308 		*path++ = '\\';
309 		len = server->ops->convert(path, maxlen-2,
310 				      name->name, name->len,
311 				      server->local_nls, server->remote_nls);
312 		if (len < 0)
313 			return len;
314 		path += len;
315 		maxlen -= len+1;
316 	}
317 	/* maxlen is at least 1 */
318 	*path++ = '\0';
319 	return path-buf;
320 }
321 
smb_encode_path(struct smb_sb_info * server,char * buf,int maxlen,struct dentry * dir,struct qstr * name)322 static int smb_encode_path(struct smb_sb_info *server, char *buf, int maxlen,
323 			   struct dentry *dir, struct qstr *name)
324 {
325 	int result;
326 
327 	result = smb_build_path(server, buf, maxlen, dir, name);
328 	if (result < 0)
329 		goto out;
330 	if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS)
331 		str_upper(buf, result);
332 out:
333 	return result;
334 }
335 
smb_simple_encode_path(struct smb_sb_info * server,char ** p,struct dentry * entry,struct qstr * name)336 static int smb_simple_encode_path(struct smb_sb_info *server, char **p,
337 			  struct dentry * entry, struct qstr * name)
338 {
339 	char *s = *p;
340 	int res;
341 	int maxlen = ((char *)server->packet + server->packet_size) - s;
342 
343 	if (!maxlen)
344 		return -ENAMETOOLONG;
345 	*s++ = 4;
346 	res = smb_encode_path(server, s, maxlen-1, entry, name);
347 	if (res < 0)
348 		return res;
349 	*p = s + res;
350 	return 0;
351 }
352 
353 /* The following are taken directly from msdos-fs */
354 
355 /* Linear day numbers of the respective 1sts in non-leap years. */
356 
357 static int day_n[] =
358 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
359 		  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
360 
361 
362 static time_t
utc2local(struct smb_sb_info * server,time_t time)363 utc2local(struct smb_sb_info *server, time_t time)
364 {
365 	return time - server->opt.serverzone*60;
366 }
367 
368 static time_t
local2utc(struct smb_sb_info * server,time_t time)369 local2utc(struct smb_sb_info *server, time_t time)
370 {
371 	return time + server->opt.serverzone*60;
372 }
373 
374 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
375 
376 static time_t
date_dos2unix(struct smb_sb_info * server,__u16 date,__u16 time)377 date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time)
378 {
379 	int month, year;
380 	time_t secs;
381 
382 	/* first subtract and mask after that... Otherwise, if
383 	   date == 0, bad things happen */
384 	month = ((date >> 5) - 1) & 15;
385 	year = date >> 9;
386 	secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
387 	    ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
388 						   month < 2 ? 1 : 0) + 3653);
389 	/* days since 1.1.70 plus 80's leap day */
390 	return local2utc(server, secs);
391 }
392 
393 
394 /* Convert linear UNIX date to a MS-DOS time/date pair. */
395 
396 static void
date_unix2dos(struct smb_sb_info * server,int unix_date,__u16 * date,__u16 * time)397 date_unix2dos(struct smb_sb_info *server,
398 	      int unix_date, __u16 *date, __u16 *time)
399 {
400 	int day, year, nl_day, month;
401 
402 	unix_date = utc2local(server, unix_date);
403 	if (unix_date < 315532800)
404 		unix_date = 315532800;
405 
406 	*time = (unix_date % 60) / 2 +
407 		(((unix_date / 60) % 60) << 5) +
408 		(((unix_date / 3600) % 24) << 11);
409 
410 	day = unix_date / 86400 - 3652;
411 	year = day / 365;
412 	if ((year + 3) / 4 + 365 * year > day)
413 		year--;
414 	day -= (year + 3) / 4 + 365 * year;
415 	if (day == 59 && !(year & 3)) {
416 		nl_day = day;
417 		month = 2;
418 	} else {
419 		nl_day = (year & 3) || day <= 59 ? day : day - 1;
420 		for (month = 0; month < 12; month++)
421 			if (day_n[month] > nl_day)
422 				break;
423 	}
424 	*date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9);
425 }
426 
427 /* The following are taken from fs/ntfs/util.c */
428 
429 #define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
430 
431 /*
432  * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
433  * into Unix UTC (based 1970-01-01, in seconds).
434  */
435 static time_t
smb_ntutc2unixutc(u64 ntutc)436 smb_ntutc2unixutc(u64 ntutc)
437 {
438 	/* FIXME: what about the timezone difference? */
439 	/* Subtract the NTFS time offset, then convert to 1s intervals. */
440 	u64 t = ntutc - NTFS_TIME_OFFSET;
441 	do_div(t, 10000000);
442 	return (time_t)t;
443 }
444 
445 static u64
smb_unixutc2ntutc(time_t t)446 smb_unixutc2ntutc(time_t t)
447 {
448 	/* Note: timezone conversion is probably wrong. */
449 	return ((u64)t) * 10000000 + NTFS_TIME_OFFSET;
450 }
451 
452 #define MAX_FILE_MODE   6
453 static mode_t file_mode[] = {
454 	S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK
455 };
456 
smb_filetype_to_mode(u32 filetype)457 static int smb_filetype_to_mode(u32 filetype)
458 {
459 	if (filetype > MAX_FILE_MODE) {
460 		PARANOIA("Filetype out of range: %d\n", filetype);
461 		return S_IFREG;
462 	}
463 	return file_mode[filetype];
464 }
465 
smb_filetype_from_mode(int mode)466 static u32 smb_filetype_from_mode(int mode)
467 {
468 	if (mode & S_IFREG)
469 		return UNIX_TYPE_FILE;
470 	if (mode & S_IFDIR)
471 		return UNIX_TYPE_DIR;
472 	if (mode & S_IFLNK)
473 		return UNIX_TYPE_SYMLINK;
474 	if (mode & S_IFCHR)
475 		return UNIX_TYPE_CHARDEV;
476 	if (mode & S_IFBLK)
477 		return UNIX_TYPE_BLKDEV;
478 	if (mode & S_IFIFO)
479 		return UNIX_TYPE_FIFO;
480 	if (mode & S_IFSOCK)
481 		return UNIX_TYPE_SOCKET;
482 	return UNIX_TYPE_UNKNOWN;
483 }
484 
485 
486 /*****************************************************************************/
487 /*                                                                           */
488 /*  Support section.                                                         */
489 /*                                                                           */
490 /*****************************************************************************/
491 
492 __u32
smb_len(__u8 * p)493 smb_len(__u8 * p)
494 {
495 	return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3);
496 }
497 
498 static __u16
smb_bcc(__u8 * packet)499 smb_bcc(__u8 * packet)
500 {
501 	int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16);
502 	return WVAL(packet, pos);
503 }
504 
505 /* smb_valid_packet: We check if packet fulfills the basic
506    requirements of a smb packet */
507 
508 static int
smb_valid_packet(__u8 * packet)509 smb_valid_packet(__u8 * packet)
510 {
511 	return (packet[4] == 0xff
512 		&& packet[5] == 'S'
513 		&& packet[6] == 'M'
514 		&& packet[7] == 'B'
515 		&& (smb_len(packet) + 4 == SMB_HEADER_LEN
516 		    + SMB_WCT(packet) * 2 + SMB_BCC(packet)));
517 }
518 
519 /* smb_verify: We check if we got the answer we expected, and if we
520    got enough data. If bcc == -1, we don't care. */
521 
522 static int
smb_verify(__u8 * packet,int command,int wct,int bcc)523 smb_verify(__u8 * packet, int command, int wct, int bcc)
524 {
525 	if (SMB_CMD(packet) != command)
526 		goto bad_command;
527 	if (SMB_WCT(packet) < wct)
528 		goto bad_wct;
529 	if (bcc != -1 && SMB_BCC(packet) < bcc)
530 		goto bad_bcc;
531 	return 0;
532 
533 bad_command:
534 	printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n",
535 	       command, SMB_CMD(packet));
536 	goto fail;
537 bad_wct:
538 	printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n",
539 	       command, wct, SMB_WCT(packet));
540 	goto fail;
541 bad_bcc:
542 	printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n",
543 	       command, bcc, SMB_BCC(packet));
544 fail:
545 	return -EIO;
546 }
547 
548 /*
549  * Returns the maximum read or write size for the "payload". Making all of the
550  * packet fit within the negotiated max_xmit size.
551  *
552  * N.B. Since this value is usually computed before locking the server,
553  * the server's packet size must never be decreased!
554  */
555 static inline int
smb_get_xmitsize(struct smb_sb_info * server,int overhead)556 smb_get_xmitsize(struct smb_sb_info *server, int overhead)
557 {
558 	return server->opt.max_xmit - overhead;
559 }
560 
561 /*
562  * Calculate the maximum read size
563  */
564 int
smb_get_rsize(struct smb_sb_info * server)565 smb_get_rsize(struct smb_sb_info *server)
566 {
567 	/* readX has 12 parameters, read has 5 */
568 	int overhead = SMB_HEADER_LEN + 12 * sizeof(__u16) + 2 + 1 + 2;
569 	int size = smb_get_xmitsize(server, overhead);
570 
571 	VERBOSE("packet=%d, xmit=%d, size=%d\n",
572 		server->packet_size, server->opt.max_xmit, size);
573 
574 	return size;
575 }
576 
577 /*
578  * Calculate the maximum write size
579  */
580 int
smb_get_wsize(struct smb_sb_info * server)581 smb_get_wsize(struct smb_sb_info *server)
582 {
583 	/* writeX has 14 parameters, write has 5 */
584 	int overhead = SMB_HEADER_LEN + 14 * sizeof(__u16) + 2 + 1 + 2;
585 	int size = smb_get_xmitsize(server, overhead);
586 
587 	VERBOSE("packet=%d, xmit=%d, size=%d\n",
588 		server->packet_size, server->opt.max_xmit, size);
589 
590 	return size;
591 }
592 
593 /*
594  * Convert SMB error codes to -E... errno values.
595  */
596 int
smb_errno(struct smb_sb_info * server)597 smb_errno(struct smb_sb_info *server)
598 {
599 	int errcls = server->rcls;
600 	int error  = server->err;
601 	char *class = "Unknown";
602 
603 	VERBOSE("errcls %d  code %d  from command 0x%x\n",
604 		errcls, error, SMB_CMD(server->packet));
605 
606 	if (errcls == ERRDOS) {
607 		switch (error) {
608 		case ERRbadfunc:
609 			return -EINVAL;
610 		case ERRbadfile:
611 		case ERRbadpath:
612 			return -ENOENT;
613 		case ERRnofids:
614 			return -EMFILE;
615 		case ERRnoaccess:
616 			return -EACCES;
617 		case ERRbadfid:
618 			return -EBADF;
619 		case ERRbadmcb:
620 			return -EREMOTEIO;
621 		case ERRnomem:
622 			return -ENOMEM;
623 		case ERRbadmem:
624 			return -EFAULT;
625 		case ERRbadenv:
626 		case ERRbadformat:
627 			return -EREMOTEIO;
628 		case ERRbadaccess:
629 			return -EACCES;
630 		case ERRbaddata:
631 			return -E2BIG;
632 		case ERRbaddrive:
633 			return -ENXIO;
634 		case ERRremcd:
635 			return -EREMOTEIO;
636 		case ERRdiffdevice:
637 			return -EXDEV;
638 		case ERRnofiles:
639 			return -ENOENT;
640 		case ERRbadshare:
641 			return -ETXTBSY;
642 		case ERRlock:
643 			return -EDEADLK;
644 		case ERRfilexists:
645 			return -EEXIST;
646 		case ERROR_INVALID_PARAMETER:
647 			return -EINVAL;
648 		case ERROR_DISK_FULL:
649 			return -ENOSPC;
650 		case ERROR_INVALID_NAME:
651 			return -ENOENT;
652 		case ERROR_DIR_NOT_EMPTY:
653 			return -ENOTEMPTY;
654 		case ERROR_NOT_LOCKED:
655                        return -ENOLCK;
656 		case ERROR_ALREADY_EXISTS:
657 			return -EEXIST;
658 		default:
659 			class = "ERRDOS";
660 			goto err_unknown;
661 		}
662 	} else if (errcls == ERRSRV) {
663 		switch (error) {
664 		/* N.B. This is wrong ... EIO ? */
665 		case ERRerror:
666 			return -ENFILE;
667 		case ERRbadpw:
668 			return -EINVAL;
669 		case ERRbadtype:
670 			return -EIO;
671 		case ERRaccess:
672 			return -EACCES;
673 		/*
674 		 * This is a fatal error, as it means the "tree ID"
675 		 * for this connection is no longer valid. We map
676 		 * to a special error code and get a new connection.
677 		 */
678 		case ERRinvnid:
679 			return -EBADSLT;
680 		default:
681 			class = "ERRSRV";
682 			goto err_unknown;
683 		}
684 	} else if (errcls == ERRHRD) {
685 		switch (error) {
686 		case ERRnowrite:
687 			return -EROFS;
688 		case ERRbadunit:
689 			return -ENODEV;
690 		case ERRnotready:
691 			return -EUCLEAN;
692 		case ERRbadcmd:
693 		case ERRdata:
694 			return -EIO;
695 		case ERRbadreq:
696 			return -ERANGE;
697 		case ERRbadshare:
698 			return -ETXTBSY;
699 		case ERRlock:
700 			return -EDEADLK;
701 		case ERRdiskfull:
702 			return -ENOSPC;
703 		default:
704 			class = "ERRHRD";
705 			goto err_unknown;
706 		}
707 	} else if (errcls == ERRCMD) {
708 		class = "ERRCMD";
709 	} else if (errcls == SUCCESS) {
710 		return 0;	/* This is the only valid 0 return */
711 	}
712 
713 err_unknown:
714 	printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
715 	       class, error, SMB_CMD(server->packet));
716 	return -EIO;
717 }
718 
719 /*
720  * smb_retry: This function should be called when smb_request_ok has
721  * indicated an error. If the error was indicated because the
722  * connection was killed, we try to reconnect. If smb_retry returns 0,
723  * the error was indicated for another reason, so a retry would not be
724  * of any use.
725  * N.B. The server must be locked for this call.
726  */
727 static int
smb_retry(struct smb_sb_info * server)728 smb_retry(struct smb_sb_info *server)
729 {
730 	pid_t pid = server->conn_pid;
731 	int error, result = 0;
732 
733 	if (server->state == CONN_VALID || server->state == CONN_RETRYING)
734 		goto out;
735 
736 	smb_close_socket(server);
737 
738 	if (pid == 0) {
739 		printk(KERN_ERR "smb_retry: no connection process\n");
740 		server->state = CONN_RETRIED;
741 		goto out;
742 	}
743 
744 	/*
745 	 * Change state so that only one retry per server will be started.
746 	 */
747 	server->state = CONN_RETRYING;
748 
749 	/*
750 	 * Note: use the "priv" flag, as a user process may need to reconnect.
751 	 */
752 	error = kill_proc(pid, SIGUSR1, 1);
753 	if (error) {
754 		/* FIXME: this is fatal */
755 		printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error);
756 		goto out;
757 	}
758 	VERBOSE("signalled pid %d, waiting for new connection\n", pid);
759 
760 	/*
761 	 * Wait for the new connection.
762 	 */
763 	smb_unlock_server(server);
764 	interruptible_sleep_on_timeout(&server->wait, server->mnt->timeo*HZ);
765 	smb_lock_server(server);
766 	if (signal_pending(current))
767 		printk(KERN_INFO "smb_retry: caught signal\n");
768 
769 	/*
770 	 * Check for a valid connection.
771 	 */
772 	if (server->state == CONN_VALID) {
773 		/* This should be changed to VERBOSE, except many smbfs
774 		   problems is with the userspace daemon not reconnecting. */
775 		PARANOIA("successful, new pid=%d, generation=%d\n",
776 			 server->conn_pid, server->generation);
777 		result = 1;
778 	} else if (server->state == CONN_RETRYING) {
779 		/* allow further attempts later */
780 		server->state = CONN_RETRIED;
781 	}
782 
783 out:
784 	return result;
785 }
786 
787 /* smb_request_ok: We expect the server to be locked. Then we do the
788    request and check the answer completely. When smb_request_ok
789    returns 0, you can be quite sure that everything went well. When
790    the answer is <=0, the returned number is a valid unix errno. */
791 
792 static int
smb_request_ok(struct smb_sb_info * s,int command,int wct,int bcc)793 smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc)
794 {
795 	int result = -EIO;
796 
797 	s->rcls = 0;
798 	s->err = 0;
799 
800 	/* Make sure we have a connection */
801 	if (s->state != CONN_VALID) {
802 		if (!smb_retry(s))
803 			goto out;
804 	}
805 
806 	if (smb_request(s) < 0) {
807 		DEBUG1("smb_request failed\n");
808 		goto out;
809 	}
810 	if (smb_valid_packet(s->packet) != 0) {
811 		PARANOIA("invalid packet!\n");
812 		goto out;
813 	}
814 
815 	/*
816 	 * Check for server errors.
817 	 */
818 	if (s->rcls != 0) {
819 		result = smb_errno(s);
820 		if (!result)
821 			printk(KERN_DEBUG "smb_request_ok: rcls=%d, err=%d mapped to 0\n",
822 				s->rcls, s->err);
823 		/*
824 		 * Exit now even if the error was squashed ...
825 		 * packet verify will fail anyway.
826 		 */
827 		goto out;
828 	}
829 	result = smb_verify(s->packet, command, wct, bcc);
830 
831 out:
832 	return result;
833 }
834 
835 /*
836  * This implements the NEWCONN ioctl. It installs the server pid,
837  * sets server->state to CONN_VALID, and wakes up the waiting process.
838  */
839 int
smb_newconn(struct smb_sb_info * server,struct smb_conn_opt * opt)840 smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
841 {
842 	struct file *filp;
843 	int error;
844 
845 	VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);
846 
847 	smb_lock_server(server);
848 
849 	/*
850 	 * Make sure we don't already have a valid connection ...
851 	 */
852 	error = -EINVAL;
853 	if (server->state == CONN_VALID)
854 		goto out;
855 
856 	error = -EACCES;
857 	if (current->uid != server->mnt->mounted_uid &&
858 	    !capable(CAP_SYS_ADMIN))
859 		goto out;
860 
861 	error = -EBADF;
862 	filp = fget(opt->fd);
863 	if (!filp)
864 		goto out;
865 	if (!smb_valid_socket(filp->f_dentry->d_inode))
866 		goto out_putf;
867 
868 	server->sock_file = filp;
869 	server->conn_pid = current->pid;
870 	smb_catch_keepalive(server);
871 	server->opt = *opt;
872 	server->generation += 1;
873 	server->state = CONN_VALID;
874 	error = 0;
875 
876 	/* check if we have an old smbmount that uses seconds for the
877 	   serverzone */
878 	if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60)
879 		server->opt.serverzone /= 60;
880 
881 	/* now that we have an established connection we can detect the server
882 	   type and enable bug workarounds */
883 	if (server->opt.protocol < SMB_PROTOCOL_LANMAN2)
884 		install_ops(server->ops, &smb_ops_core);
885 	else if (server->opt.protocol == SMB_PROTOCOL_LANMAN2)
886 		install_ops(server->ops, &smb_ops_os2);
887 	else if (server->opt.protocol == SMB_PROTOCOL_NT1 &&
888 		 (server->opt.max_xmit < 0x1000) &&
889 		 !(server->opt.capabilities & SMB_CAP_NT_SMBS)) {
890 		/* FIXME: can we kill the WIN95 flag now? */
891 		server->mnt->flags |= SMB_MOUNT_WIN95;
892 		VERBOSE("detected WIN95 server\n");
893 		install_ops(server->ops, &smb_ops_win95);
894 	} else {
895 		/*
896 		 * Samba has max_xmit 65535
897 		 * NT4spX has max_xmit 4536 (or something like that)
898 		 * win2k has ...
899 		 */
900 		VERBOSE("detected NT1 (Samba, NT4/5) server\n");
901 		install_ops(server->ops, &smb_ops_winNT);
902 	}
903 
904 	/* FIXME: the win9x code wants to modify these ... (seek/trunc bug) */
905 	if (server->mnt->flags & SMB_MOUNT_OLDATTR) {
906 		server->ops->getattr = smb_proc_getattr_core;
907 	} else if (server->mnt->flags & SMB_MOUNT_DIRATTR) {
908 		server->ops->getattr = smb_proc_getattr_ff;
909 	}
910 
911 	/* Decode server capabilities */
912 	if (server->opt.capabilities & SMB_CAP_LARGE_FILES) {
913 		/* Should be ok to set this now, as no one can access the
914 		   mount until the connection has been established. */
915 		SB_of(server)->s_maxbytes = ~0ULL >> 1;
916 		VERBOSE("LFS enabled\n");
917 	}
918 #ifndef CONFIG_SMB_UNIX
919 	server->opt.capabilities &= ~SMB_CAP_UNIX;
920 #endif
921 	if (server->opt.capabilities & SMB_CAP_UNIX) {
922 		struct inode *inode;
923 		VERBOSE("Using UNIX CIFS extensions\n");
924 		install_ops(server->ops, &smb_ops_unix);
925 		inode = SB_of(server)->s_root->d_inode;
926 		if (inode)
927 			inode->i_op = &smb_dir_inode_operations_unix;
928 	}
929 
930 	VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
931 		server->opt.protocol, server->opt.max_xmit, server->conn_pid,
932 		server->opt.capabilities);
933 
934 	/* Make sure we can fit a message of the negotiated size in our
935 	   packet buffer. */
936 	if (server->opt.max_xmit > server->packet_size) {
937 		int len = smb_round_length(server->opt.max_xmit);
938 		char *buf = smb_vmalloc(len);
939 		if (buf) {
940 			if (server->packet)
941 				smb_vfree(server->packet);
942 			server->packet = buf;
943 			server->packet_size = len;
944 		} else {
945 			/* else continue with the too small buffer? */
946 			PARANOIA("Failed to allocate new packet buffer: "
947 				 "max_xmit=%d, packet_size=%d\n",
948 				 server->opt.max_xmit, server->packet_size);
949 			server->opt.max_xmit = server->packet_size;
950 		}
951 	}
952 
953 	if (server->opt.capabilities & SMB_CAP_UNIX)
954 		smb_proc_query_cifsunix(server);
955 
956 out:
957 	smb_unlock_server(server);
958 	smb_wakeup(server);
959 	return error;
960 
961 out_putf:
962 	fput(filp);
963 	goto out;
964 }
965 
966 int
smb_wakeup(struct smb_sb_info * server)967 smb_wakeup(struct smb_sb_info *server)
968 {
969 	wake_up_interruptible(&server->wait);
970 	return 0;
971 }
972 
973 /* smb_setup_header: We completely set up the packet. You only have to
974    insert the command-specific fields */
975 
976 __u8 *
smb_setup_header(struct smb_sb_info * server,__u8 command,__u16 wct,__u16 bcc)977 smb_setup_header(struct smb_sb_info * server, __u8 command, __u16 wct, __u16 bcc)
978 {
979 	__u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2;
980 	__u8 *p = server->packet;
981 	__u8 *buf = server->packet;
982 
983 	if (xmit_len > server->packet_size)
984 		printk(KERN_DEBUG "smb_setup_header: "
985 		       "Aieee, xmit len > packet! len=%d, size=%d\n",
986 		       xmit_len, server->packet_size);
987 
988 	p = smb_encode_smb_length(p, xmit_len - 4);
989 
990 	*p++ = 0xff;
991 	*p++ = 'S';
992 	*p++ = 'M';
993 	*p++ = 'B';
994 	*p++ = command;
995 
996 	memset(p, '\0', 19);
997 	p += 19;
998 	p += 8;
999 
1000 	WSET(buf, smb_tid, server->opt.tid);
1001 	WSET(buf, smb_pid, 1);
1002 	WSET(buf, smb_uid, server->opt.server_uid);
1003 	WSET(buf, smb_mid, 1);
1004 
1005 	if (server->opt.protocol > SMB_PROTOCOL_CORE)
1006 	{
1007 		*(buf+smb_flg) = 0x8;
1008 		WSET(buf, smb_flg2, 0x3);
1009 	}
1010 	*p++ = wct;		/* wct */
1011 	p += 2 * wct;
1012 	WSET(p, 0, bcc);
1013 	return p + 2;
1014 }
1015 
1016 static void
smb_setup_bcc(struct smb_sb_info * server,__u8 * p)1017 smb_setup_bcc(struct smb_sb_info *server, __u8 * p)
1018 {
1019 	__u8 *packet = server->packet;
1020 	__u8 *pbcc = packet + SMB_HEADER_LEN + 2 * SMB_WCT(packet);
1021 	__u16 bcc = p - (pbcc + 2);
1022 
1023 	WSET(pbcc, 0, bcc);
1024 	smb_encode_smb_length(packet,
1025 			      SMB_HEADER_LEN + 2 * SMB_WCT(packet) - 2 + bcc);
1026 }
1027 
1028 /*
1029  * Called with the server locked
1030  */
1031 static int
smb_proc_seek(struct smb_sb_info * server,__u16 fileid,__u16 mode,off_t offset)1032 smb_proc_seek(struct smb_sb_info *server, __u16 fileid,
1033 	      __u16 mode, off_t offset)
1034 {
1035 	int result;
1036 
1037 	smb_setup_header(server, SMBlseek, 4, 0);
1038 	WSET(server->packet, smb_vwv0, fileid);
1039 	WSET(server->packet, smb_vwv1, mode);
1040 	DSET(server->packet, smb_vwv2, offset);
1041 
1042 	result = smb_request_ok(server, SMBlseek, 2, 0);
1043 	if (result < 0) {
1044 		result = 0;
1045 		goto out;
1046 	}
1047 
1048 	result = DVAL(server->packet, smb_vwv0);
1049 out:
1050 	return result;
1051 }
1052 
1053 /*
1054  * We're called with the server locked, and we leave it that way.
1055  */
1056 static int
smb_proc_open(struct smb_sb_info * server,struct dentry * dentry,int wish)1057 smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
1058 {
1059 	struct inode *ino = dentry->d_inode;
1060 	int mode, read_write = 0x42, read_only = 0x40;
1061 	int res;
1062 	char *p;
1063 
1064 	/*
1065 	 * Attempt to open r/w, unless there are no write privileges.
1066 	 */
1067 	mode = read_write;
1068 	if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
1069 		mode = read_only;
1070 #if 0
1071 	/* FIXME: why is this code not in? below we fix it so that a caller
1072 	   wanting RO doesn't get RW. smb_revalidate_inode does some
1073 	   optimization based on access mode. tail -f needs it to be correct.
1074 
1075 	   We must open rw since we don't do the open if called a second time
1076 	   with different 'wish'. Is that not supported by smb servers? */
1077 	if (!(wish & (O_WRONLY | O_RDWR)))
1078 		mode = read_only;
1079 #endif
1080 
1081       retry:
1082 	p = smb_setup_header(server, SMBopen, 2, 0);
1083 	WSET(server->packet, smb_vwv0, mode);
1084 	WSET(server->packet, smb_vwv1, aSYSTEM | aHIDDEN | aDIR);
1085 	res = smb_simple_encode_path(server, &p, dentry, NULL);
1086 	if (res < 0)
1087 		goto out;
1088 	smb_setup_bcc(server, p);
1089 
1090 	res = smb_request_ok(server, SMBopen, 7, 0);
1091 	if (res != 0) {
1092 		if (smb_retry(server))
1093 			goto retry;
1094 
1095 		if (mode == read_write &&
1096 		    (res == -EACCES || res == -ETXTBSY || res == -EROFS))
1097 		{
1098 			VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
1099 				DENTRY_PATH(dentry), res);
1100 			mode = read_only;
1101 			goto retry;
1102 		}
1103 		goto out;
1104 	}
1105 	/* We should now have data in vwv[0..6]. */
1106 
1107 	ino->u.smbfs_i.fileid = WVAL(server->packet, smb_vwv0);
1108 	ino->u.smbfs_i.attr   = WVAL(server->packet, smb_vwv1);
1109 	/* smb_vwv2 has mtime */
1110 	/* smb_vwv4 has size  */
1111 	ino->u.smbfs_i.access = (WVAL(server->packet, smb_vwv6) & SMB_ACCMASK);
1112 	ino->u.smbfs_i.open = server->generation;
1113 
1114 out:
1115 	return res;
1116 }
1117 
1118 /*
1119  * Make sure the file is open, and check that the access
1120  * is compatible with the desired access.
1121  */
1122 int
smb_open(struct dentry * dentry,int wish)1123 smb_open(struct dentry *dentry, int wish)
1124 {
1125 	struct inode *inode = dentry->d_inode;
1126 	int result;
1127 
1128 	result = -ENOENT;
1129 	if (!inode) {
1130 		printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
1131 		       DENTRY_PATH(dentry));
1132 		goto out;
1133 	}
1134 
1135 	if (!smb_is_open(inode)) {
1136 		struct smb_sb_info *server = server_from_inode(inode);
1137 		smb_lock_server(server);
1138 		result = 0;
1139 		if (!smb_is_open(inode))
1140 			result = smb_proc_open(server, dentry, wish);
1141 		smb_unlock_server(server);
1142 		if (result) {
1143 			PARANOIA("%s/%s open failed, result=%d\n",
1144 				 DENTRY_PATH(dentry), result);
1145 			goto out;
1146 		}
1147 		/*
1148 		 * A successful open means the path is still valid ...
1149 		 */
1150 		smb_renew_times(dentry);
1151 	}
1152 
1153 	/*
1154 	 * Check whether the access is compatible with the desired mode.
1155 	 */
1156 	result = 0;
1157 	if (inode->u.smbfs_i.access != wish &&
1158 	    inode->u.smbfs_i.access != SMB_O_RDWR)
1159 	{
1160 		PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
1161 			 DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
1162 		result = -EACCES;
1163 	}
1164 out:
1165 	return result;
1166 }
1167 
1168 /* We're called with the server locked */
1169 
1170 static int
smb_proc_close(struct smb_sb_info * server,__u16 fileid,__u32 mtime)1171 smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime)
1172 {
1173 	smb_setup_header(server, SMBclose, 3, 0);
1174 	WSET(server->packet, smb_vwv0, fileid);
1175 	DSET(server->packet, smb_vwv1, utc2local(server, mtime));
1176 	return smb_request_ok(server, SMBclose, 0, 0);
1177 }
1178 
1179 /*
1180  * Called with the server locked.
1181  *
1182  * Win NT 4.0 has an apparent bug in that it fails to update the
1183  * modify time when writing to a file. As a workaround, we update
1184  * both modify and access time locally, and post the times to the
1185  * server when closing the file.
1186  */
1187 static int
smb_proc_close_inode(struct smb_sb_info * server,struct inode * ino)1188 smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino)
1189 {
1190 	int result = 0;
1191 	if (smb_is_open(ino))
1192 	{
1193 		/*
1194 		 * We clear the open flag in advance, in case another
1195  		 * process observes the value while we block below.
1196 		 */
1197 		ino->u.smbfs_i.open = 0;
1198 
1199 		/*
1200 		 * Kludge alert: SMB timestamps are accurate only to
1201 		 * two seconds ... round the times to avoid needless
1202 		 * cache invalidations!
1203 		 */
1204 		if (ino->i_mtime & 1)
1205 			ino->i_mtime--;
1206 		if (ino->i_atime & 1)
1207 			ino->i_atime--;
1208 		/*
1209 		 * If the file is open with write permissions,
1210 		 * update the time stamps to sync mtime and atime.
1211 		 */
1212 		if ((server->opt.capabilities & SMB_CAP_UNIX) == 0 &&
1213 		    (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) &&
1214 		    !(ino->u.smbfs_i.access == SMB_O_RDONLY))
1215 		{
1216 			struct smb_fattr fattr;
1217 			smb_get_inode_attr(ino, &fattr);
1218 			smb_proc_setattr_ext(server, ino, &fattr);
1219 		}
1220 
1221 		result = smb_proc_close(server, ino->u.smbfs_i.fileid,
1222 						ino->i_mtime);
1223 		/*
1224 		 * Force a revalidation after closing ... some servers
1225 		 * don't post the size until the file has been closed.
1226 		 */
1227 		if (server->opt.protocol < SMB_PROTOCOL_NT1)
1228 			ino->u.smbfs_i.oldmtime = 0;
1229 		ino->u.smbfs_i.closed = jiffies;
1230 	}
1231 	return result;
1232 }
1233 
1234 int
smb_close(struct inode * ino)1235 smb_close(struct inode *ino)
1236 {
1237 	int result = 0;
1238 
1239 	if (smb_is_open(ino)) {
1240 		struct smb_sb_info *server = server_from_inode(ino);
1241 		smb_lock_server(server);
1242 		result = smb_proc_close_inode(server, ino);
1243 		smb_unlock_server(server);
1244 	}
1245 	return result;
1246 }
1247 
1248 /*
1249  * This is used to close a file following a failed instantiate.
1250  * Since we don't have an inode, we can't use any of the above.
1251  */
1252 int
smb_close_fileid(struct dentry * dentry,__u16 fileid)1253 smb_close_fileid(struct dentry *dentry, __u16 fileid)
1254 {
1255 	struct smb_sb_info *server = server_from_dentry(dentry);
1256 	int result;
1257 
1258 	smb_lock_server(server);
1259 	result = smb_proc_close(server, fileid, CURRENT_TIME);
1260 	smb_unlock_server(server);
1261 	return result;
1262 }
1263 
1264 /* In smb_proc_read and smb_proc_write we do not retry, because the
1265    file-id would not be valid after a reconnection. */
1266 
1267 static int
smb_proc_read(struct inode * inode,loff_t offset,int count,char * data)1268 smb_proc_read(struct inode *inode, loff_t offset, int count, char *data)
1269 {
1270 	struct smb_sb_info *server = server_from_inode(inode);
1271 	__u16 returned_count, data_len;
1272 	unsigned char *buf;
1273 	int result;
1274 
1275 	smb_lock_server(server);
1276 	smb_setup_header(server, SMBread, 5, 0);
1277 	buf = server->packet;
1278 	WSET(buf, smb_vwv0, inode->u.smbfs_i.fileid);
1279 	WSET(buf, smb_vwv1, count);
1280 	DSET(buf, smb_vwv2, offset);
1281 	WSET(buf, smb_vwv4, 0);
1282 
1283 	result = smb_request_ok(server, SMBread, 5, -1);
1284 	if (result < 0)
1285 		goto out;
1286 	returned_count = WVAL(server->packet, smb_vwv0);
1287 
1288 	buf = SMB_BUF(server->packet);
1289 	data_len = WVAL(buf, 1);
1290 
1291 	/* we can NOT simply trust the data_len given by the server ... */
1292 	if (data_len > count ||
1293 		(buf+3 - server->packet) + data_len > server->packet_size) {
1294 		printk(KERN_ERR "smb_proc_read: invalid data length/offset!! "
1295 		       "%d > %d || (%p - %p) + %d > %d\n",
1296 		       data_len, count,
1297 		       buf+3, server->packet, data_len, server->packet_size);
1298 		result = -EIO;
1299 		goto out;
1300 	}
1301 
1302 	memcpy(data, buf+3, data_len);
1303 
1304 	if (returned_count != data_len) {
1305 		printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
1306 		printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
1307 		       returned_count, data_len);
1308 	}
1309 	result = data_len;
1310 
1311 out:
1312 	VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
1313 		inode->i_ino, inode->u.smbfs_i.fileid, count, result);
1314 	smb_unlock_server(server);
1315 	return result;
1316 }
1317 
1318 static int
smb_proc_write(struct inode * inode,loff_t offset,int count,const char * data)1319 smb_proc_write(struct inode *inode, loff_t offset, int count, const char *data)
1320 {
1321 	struct smb_sb_info *server = server_from_inode(inode);
1322 	int result;
1323 	__u8 *p;
1324 	__u16 fileid = inode->u.smbfs_i.fileid;
1325 
1326 	VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld, packet_size=%d\n",
1327 		inode->i_ino, inode->u.smbfs_i.fileid, count, offset,
1328 		server->packet_size);
1329 
1330 	smb_lock_server(server);
1331 	p = smb_setup_header(server, SMBwrite, 5, count + 3);
1332 	WSET(server->packet, smb_vwv0, fileid);
1333 	WSET(server->packet, smb_vwv1, count);
1334 	DSET(server->packet, smb_vwv2, offset);
1335 	WSET(server->packet, smb_vwv4, 0);
1336 
1337 	*p++ = 1;
1338 	WSET(p, 0, count);
1339 	memcpy(p+2, data, count);
1340 
1341 	result = smb_request_ok(server, SMBwrite, 1, 0);
1342 	if (result >= 0)
1343 		result = WVAL(server->packet, smb_vwv0);
1344 
1345 	smb_unlock_server(server);
1346 	return result;
1347 }
1348 
1349 /*
1350  * In smb_proc_readX and smb_proc_writeX we do not retry, because the
1351  * file-id would not be valid after a reconnection.
1352  */
1353 static int
smb_proc_readX(struct inode * inode,loff_t offset,int count,char * data)1354 smb_proc_readX(struct inode *inode, loff_t offset, int count, char *data)
1355 {
1356 	struct smb_sb_info *server = server_from_inode(inode);
1357 	u16 data_len, data_off;
1358 	unsigned char *buf;
1359 	int result;
1360 
1361 	smb_lock_server(server);
1362 	smb_setup_header(server, SMBreadX, 12, 0);
1363 	buf = server->packet;
1364 	WSET(buf, smb_vwv0, 0x00ff);
1365 	WSET(buf, smb_vwv1, 0);
1366 	WSET(buf, smb_vwv2, inode->u.smbfs_i.fileid);
1367 	DSET(buf, smb_vwv3, (u32)offset);               /* low 32 bits */
1368 	WSET(buf, smb_vwv5, count);
1369 	WSET(buf, smb_vwv6, 0);
1370 	DSET(buf, smb_vwv7, 0);
1371 	WSET(buf, smb_vwv9, 0);
1372 	DSET(buf, smb_vwv10, (u32)(offset >> 32));      /* high 32 bits */
1373 	WSET(buf, smb_vwv11, 0);
1374 
1375 	result = smb_request_ok(server, SMBreadX, 12, -1);
1376 	if (result < 0)
1377 		goto out;
1378 	data_len = WVAL(server->packet, smb_vwv5);
1379 	data_off = WVAL(server->packet, smb_vwv6);
1380 	buf = smb_base(server->packet) + data_off;
1381 
1382 	/* we can NOT simply trust the info given by the server ... */
1383 	if (data_len > count ||
1384 		(buf - server->packet) + data_len > server->packet_size) {
1385 		printk(KERN_ERR "smb_proc_readX: invalid data length/offset!! "
1386 		       "%d > %d || (%p - %p) + %d > %d\n",
1387 		       data_len, count,
1388 		       buf, server->packet, data_len, server->packet_size);
1389 		result = -EIO;
1390 		goto out;
1391 	}
1392 
1393 	memcpy(data, buf, data_len);
1394 	result = data_len;
1395 
1396 out:
1397 	smb_unlock_server(server);
1398 	VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
1399 		inode->i_ino, inode->u.smbfs_i.fileid, count, result);
1400 	return result;
1401 }
1402 
1403 static int
smb_proc_writeX(struct inode * inode,loff_t offset,int count,const char * data)1404 smb_proc_writeX(struct inode *inode, loff_t offset, int count, const char *data)
1405 {
1406 	struct smb_sb_info *server = server_from_inode(inode);
1407 	int result;
1408 	u8 *p;
1409 
1410 	VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld, packet_size=%d\n",
1411 		inode->i_ino, inode->u.smbfs_i.fileid, count, offset,
1412 		server->packet_size);
1413 
1414 	smb_lock_server(server);
1415 	p = smb_setup_header(server, SMBwriteX, 14, count + 2);
1416 	WSET(server->packet, smb_vwv0, 0x00ff);
1417 	WSET(server->packet, smb_vwv1, 0);
1418 	WSET(server->packet, smb_vwv2, inode->u.smbfs_i.fileid);
1419 	DSET(server->packet, smb_vwv3, (u32)offset);    /* low 32 bits */
1420 	DSET(server->packet, smb_vwv5, 0);
1421 	WSET(server->packet, smb_vwv7, 0);              /* write mode */
1422 	WSET(server->packet, smb_vwv8, 0);
1423 	WSET(server->packet, smb_vwv9, 0);
1424 	WSET(server->packet, smb_vwv10, count);         /* data length */
1425 	WSET(server->packet, smb_vwv11, p + 2 - smb_base(server->packet));
1426 	DSET(server->packet, smb_vwv12, (u32)(offset >> 32));
1427 	*p++ = 0;    /* FIXME: pad to short or long ... change +2 above also */
1428 	*p++ = 0;
1429 	memcpy(p, data, count);
1430 
1431 	result = smb_request_ok(server, SMBwriteX, 6, 0);
1432 	if (result >= 0)
1433 		result = WVAL(server->packet, smb_vwv2);
1434 
1435 	smb_unlock_server(server);
1436 	return result;
1437 }
1438 
1439 int
smb_proc_create(struct dentry * dentry,__u16 attr,time_t ctime,__u16 * fileid)1440 smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid)
1441 {
1442 	struct smb_sb_info *server = server_from_dentry(dentry);
1443 	char *p;
1444 	int result;
1445 
1446 	smb_lock_server(server);
1447 
1448       retry:
1449 	p = smb_setup_header(server, SMBcreate, 3, 0);
1450 	WSET(server->packet, smb_vwv0, attr);
1451 	DSET(server->packet, smb_vwv1, utc2local(server, ctime));
1452 	result = smb_simple_encode_path(server, &p, dentry, NULL);
1453 	if (result < 0)
1454 		goto out;
1455 	smb_setup_bcc(server, p);
1456 
1457 	result = smb_request_ok(server, SMBcreate, 1, 0);
1458 	if (result < 0) {
1459 		if (smb_retry(server))
1460 			goto retry;
1461 		goto out;
1462 	}
1463 	*fileid = WVAL(server->packet, smb_vwv0);
1464 	result = 0;
1465 
1466 out:
1467 	smb_unlock_server(server);
1468 	return result;
1469 }
1470 
1471 int
smb_proc_mv(struct dentry * old_dentry,struct dentry * new_dentry)1472 smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry)
1473 {
1474 	struct smb_sb_info *server = server_from_dentry(old_dentry);
1475 	char *p;
1476 	int result;
1477 
1478 	smb_lock_server(server);
1479 
1480       retry:
1481 	p = smb_setup_header(server, SMBmv, 1, 0);
1482 	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
1483 	result = smb_simple_encode_path(server, &p, old_dentry, NULL);
1484 	if (result < 0)
1485 		goto out;
1486 	result = smb_simple_encode_path(server, &p, new_dentry, NULL);
1487 	if (result < 0)
1488 		goto out;
1489 	smb_setup_bcc(server, p);
1490 
1491 	if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0) {
1492 		if (smb_retry(server))
1493 			goto retry;
1494 		goto out;
1495 	}
1496 	result = 0;
1497 out:
1498 	smb_unlock_server(server);
1499 	return result;
1500 }
1501 
1502 /*
1503  * Code common to mkdir and rmdir.
1504  */
1505 static int
smb_proc_generic_command(struct dentry * dentry,__u8 command)1506 smb_proc_generic_command(struct dentry *dentry, __u8 command)
1507 {
1508 	struct smb_sb_info *server = server_from_dentry(dentry);
1509 	char *p;
1510 	int result;
1511 
1512 	smb_lock_server(server);
1513 
1514       retry:
1515 	p = smb_setup_header(server, command, 0, 0);
1516 	result = smb_simple_encode_path(server, &p, dentry, NULL);
1517 	if (result < 0)
1518 		goto out;
1519 	smb_setup_bcc(server, p);
1520 
1521 	result = smb_request_ok(server, command, 0, 0);
1522 	if (result < 0) {
1523 		if (smb_retry(server))
1524 			goto retry;
1525 		goto out;
1526 	}
1527 	result = 0;
1528 out:
1529 	smb_unlock_server(server);
1530 	return result;
1531 }
1532 
1533 int
smb_proc_mkdir(struct dentry * dentry)1534 smb_proc_mkdir(struct dentry *dentry)
1535 {
1536 	return smb_proc_generic_command(dentry, SMBmkdir);
1537 }
1538 
1539 int
smb_proc_rmdir(struct dentry * dentry)1540 smb_proc_rmdir(struct dentry *dentry)
1541 {
1542 	return smb_proc_generic_command(dentry, SMBrmdir);
1543 }
1544 
1545 #if SMBFS_POSIX_UNLINK
1546 /*
1547  * Removes readonly attribute from a file. Used by unlink to give posix
1548  * semantics.
1549  * Note: called with the server locked.
1550  */
1551 static int
smb_set_rw(struct dentry * dentry,struct smb_sb_info * server)1552 smb_set_rw(struct dentry *dentry,struct smb_sb_info *server)
1553 {
1554 	int result;
1555 	struct smb_fattr fattr;
1556 
1557 	/* first get current attribute */
1558 	smb_init_dirent(server, &fattr);
1559 	result = server->ops->getattr(server, dentry, &fattr);
1560 	smb_finish_dirent(server, &fattr);
1561 	if (result < 0)
1562 		return result;
1563 
1564 	/* if RONLY attribute is set, remove it */
1565 	if (fattr.attr & aRONLY) {  /* read only attribute is set */
1566 		fattr.attr &= ~aRONLY;
1567 		result = smb_proc_setattr_core(server, dentry, fattr.attr);
1568 	}
1569 	return result;
1570 }
1571 #endif
1572 
1573 int
smb_proc_unlink(struct dentry * dentry)1574 smb_proc_unlink(struct dentry *dentry)
1575 {
1576 	struct smb_sb_info *server = server_from_dentry(dentry);
1577 	int flag = 0;
1578 	char *p;
1579 	int result;
1580 
1581 	smb_lock_server(server);
1582 
1583       retry:
1584 	p = smb_setup_header(server, SMBunlink, 1, 0);
1585 	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
1586 	result = smb_simple_encode_path(server, &p, dentry, NULL);
1587 	if (result < 0)
1588 		goto out;
1589 	smb_setup_bcc(server, p);
1590 
1591 	if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0) {
1592 #if SMBFS_POSIX_UNLINK
1593 		if (result == -EACCES && !flag) {
1594 			/* Posix semantics is for the read-only state
1595 			   of a file to be ignored in unlink(). In the
1596 			   SMB world a unlink() is refused on a
1597 			   read-only file. To make things easier for
1598 			   unix users we try to override the files
1599 			   permission if the unlink fails with the
1600 			   right error.
1601 			   This introduces a race condition that could
1602 			   lead to a file being written by someone who
1603 			   shouldn't have access, but as far as I can
1604 			   tell that is unavoidable */
1605 
1606 			/* remove RONLY attribute and try again */
1607 			result = smb_set_rw(dentry,server);
1608 			if (result == 0) {
1609 				flag = 1;
1610 				goto retry;
1611 			}
1612 		}
1613 #endif
1614 		if (smb_retry(server))
1615 			goto retry;
1616 		goto out;
1617 	}
1618 	result = 0;
1619 out:
1620 	smb_unlock_server(server);
1621 	return result;
1622 }
1623 
1624 /*
1625  * Called with the server locked
1626  */
1627 int
smb_proc_flush(struct smb_sb_info * server,__u16 fileid)1628 smb_proc_flush(struct smb_sb_info *server, __u16 fileid)
1629 {
1630 	smb_setup_header(server, SMBflush, 1, 0);
1631 	WSET(server->packet, smb_vwv0, fileid);
1632 	return smb_request_ok(server, SMBflush, 0, 0);
1633 }
1634 
1635 static int
smb_proc_trunc32(struct inode * inode,loff_t length)1636 smb_proc_trunc32(struct inode *inode, loff_t length)
1637 {
1638 	/*
1639 	 * Writing 0bytes is old-SMB magic for truncating files.
1640 	 * MAX_NON_LFS should prevent this from being called with a too
1641 	 * large offset.
1642 	 */
1643 	return smb_proc_write(inode, length, 0, NULL);
1644 }
1645 
1646 static int
smb_proc_trunc64(struct inode * inode,loff_t length)1647 smb_proc_trunc64(struct inode *inode, loff_t length)
1648 {
1649 	struct smb_sb_info *server = server_from_inode(inode);
1650 	int command;
1651 	int result;
1652 	char *param = server->temp_buf;
1653 	char data[8];
1654 	unsigned char *resp_data = NULL;
1655 	unsigned char *resp_param = NULL;
1656 	int resp_data_len = 0;
1657 	int resp_param_len = 0;
1658 
1659 	smb_lock_server(server);
1660 	command = TRANSACT2_SETFILEINFO;
1661 
1662 	/* FIXME: must we also set allocation size? winNT seems to do that */
1663  retry:
1664 	WSET(param, 0, inode->u.smbfs_i.fileid);
1665 	WSET(param, 2, SMB_SET_FILE_END_OF_FILE_INFO);
1666 	WSET(param, 4, 0);
1667 	LSET(data, 0, length);
1668 	result = smb_trans2_request(server, command,
1669 				    8, data, 6, param,
1670 				    &resp_data_len, &resp_data,
1671 				    &resp_param_len, &resp_param);
1672 	if (result < 0) {
1673 		if (smb_retry(server))
1674 			goto retry;
1675 		goto out;
1676 	}
1677 	result = 0;
1678 	if (server->rcls != 0)
1679 		result = smb_errno(server);
1680 
1681 out:
1682 	smb_unlock_server(server);
1683 	return result;
1684 }
1685 
1686 static int
smb_proc_trunc95(struct inode * inode,loff_t length)1687 smb_proc_trunc95(struct inode *inode, loff_t length)
1688 {
1689 	struct smb_sb_info *server = server_from_inode(inode);
1690 	int result = smb_proc_trunc32(inode, length);
1691 
1692 	/*
1693 	 * win9x doesn't appear to update the size immediately.
1694 	 * It will return the old file size after the truncate,
1695 	 * confusing smbfs. So we force an update.
1696 	 *
1697 	 * FIXME: is this still necessary?
1698 	 */
1699 	smb_lock_server(server);
1700 	smb_proc_flush(server, inode->u.smbfs_i.fileid);
1701 	smb_unlock_server(server);
1702 	return result;
1703 }
1704 
1705 static void
smb_init_dirent(struct smb_sb_info * server,struct smb_fattr * fattr)1706 smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1707 {
1708 	memset(fattr, 0, sizeof(*fattr));
1709 
1710 	fattr->f_nlink = 1;
1711 	fattr->f_uid = server->mnt->uid;
1712 	fattr->f_gid = server->mnt->gid;
1713 	fattr->f_blksize = SMB_ST_BLKSIZE;
1714 	fattr->f_unix = 0;
1715 }
1716 
1717 static void
smb_finish_dirent(struct smb_sb_info * server,struct smb_fattr * fattr)1718 smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1719 {
1720 	if (fattr->f_unix)
1721 		return;
1722 
1723 	fattr->f_mode = server->mnt->file_mode;
1724 	if (fattr->attr & aDIR) {
1725 		fattr->f_mode = server->mnt->dir_mode;
1726 		fattr->f_size = SMB_ST_BLKSIZE;
1727 	}
1728 	/* Check the read-only flag */
1729 	if (fattr->attr & aRONLY)
1730 		fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
1731 
1732 	/* How many 512 byte blocks do we need for this file? */
1733 	fattr->f_blocks = 0;
1734 	if (fattr->f_size != 0)
1735 		fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9);
1736 	return;
1737 }
1738 
1739 void
smb_init_root_dirent(struct smb_sb_info * server,struct smb_fattr * fattr)1740 smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1741 {
1742 	smb_init_dirent(server, fattr);
1743 	fattr->attr = aDIR;
1744 	fattr->f_ino = 2; /* traditional root inode number */
1745 	fattr->f_mtime = CURRENT_TIME;
1746 	smb_finish_dirent(server, fattr);
1747 }
1748 
1749 /*
1750  * Decode a dirent for old protocols
1751  *
1752  * qname is filled with the decoded, and possibly translated, name.
1753  * fattr receives decoded attributes
1754  *
1755  * Bugs Noted:
1756  * (1) Pathworks servers may pad the name with extra spaces.
1757  */
1758 static char *
smb_decode_short_dirent(struct smb_sb_info * server,char * p,struct qstr * qname,struct smb_fattr * fattr)1759 smb_decode_short_dirent(struct smb_sb_info *server, char *p,
1760 			struct qstr *qname, struct smb_fattr *fattr)
1761 {
1762 	int len;
1763 
1764 	/*
1765 	 * SMB doesn't have a concept of inode numbers ...
1766 	 */
1767 	smb_init_dirent(server, fattr);
1768 	fattr->f_ino = 0;	/* FIXME: do we need this? */
1769 
1770 	p += SMB_STATUS_SIZE;	/* reserved (search_status) */
1771 	fattr->attr = *p;
1772 	fattr->f_mtime = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1));
1773 	fattr->f_size = DVAL(p, 5);
1774 	fattr->f_ctime = fattr->f_mtime;
1775 	fattr->f_atime = fattr->f_mtime;
1776 	qname->name = p + 9;
1777 	len = strnlen(qname->name, 12);
1778 
1779 	/*
1780 	 * Trim trailing blanks for Pathworks servers
1781 	 */
1782 	while (len > 2 && qname->name[len-1] == ' ')
1783 		len--;
1784 	qname->len = len;
1785 
1786 	smb_finish_dirent(server, fattr);
1787 
1788 #if 0
1789 	/* FIXME: These only work for ascii chars, and recent smbmount doesn't
1790 	   allow the flag to be set anyway. It kills const. Remove? */
1791 	switch (server->opt.case_handling) {
1792 	case SMB_CASE_UPPER:
1793 		str_upper(entry->name, len);
1794 		break;
1795 	case SMB_CASE_LOWER:
1796 		str_lower(entry->name, len);
1797 		break;
1798 	default:
1799 		break;
1800 	}
1801 #endif
1802 
1803 	qname->len = 0;
1804 	len = server->ops->convert(server->name_buf, SMB_MAXNAMELEN,
1805 			    qname->name, len,
1806 			    server->remote_nls, server->local_nls);
1807 	if (len > 0) {
1808 		qname->len = len;
1809 		qname->name = server->name_buf;
1810 		DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name);
1811 	}
1812 
1813 	return p + 22;
1814 }
1815 
1816 /*
1817  * This routine is used to read in directory entries from the network.
1818  * Note that it is for short directory name seeks, i.e.: protocol <
1819  * SMB_PROTOCOL_LANMAN2
1820  */
1821 static int
smb_proc_readdir_short(struct file * filp,void * dirent,filldir_t filldir,struct smb_cache_control * ctl)1822 smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
1823 		       struct smb_cache_control *ctl)
1824 {
1825 	struct dentry *dir = filp->f_dentry;
1826 	struct smb_sb_info *server = server_from_dentry(dir);
1827 	struct qstr qname;
1828 	struct smb_fattr fattr;
1829 	char *p;
1830 	int result;
1831 	int i, first, entries_seen, entries;
1832 	int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE;
1833 	__u16 bcc;
1834 	__u16 count;
1835 	char status[SMB_STATUS_SIZE];
1836 	static struct qstr mask = { "*.*", 3, 0 };
1837 	unsigned char *last_status;
1838 
1839 	VERBOSE("%s/%s\n", DENTRY_PATH(dir));
1840 
1841 	smb_lock_server(server);
1842 
1843 	first = 1;
1844 	entries = 0;
1845 	entries_seen = 2; /* implicit . and .. */
1846 
1847 	while (1) {
1848 		p = smb_setup_header(server, SMBsearch, 2, 0);
1849 		WSET(server->packet, smb_vwv0, entries_asked);
1850 		WSET(server->packet, smb_vwv1, aDIR);
1851 		if (first == 1) {
1852 			result = smb_simple_encode_path(server, &p, dir, &mask);
1853 			if (result < 0)
1854 				goto unlock_return;
1855 			if (p + 3 > (char*)server->packet+server->packet_size) {
1856 				result = -ENAMETOOLONG;
1857 				goto unlock_return;
1858 			}
1859 			*p++ = 5;
1860 			WSET(p, 0, 0);
1861 			p += 2;
1862 			first = 0;
1863 		} else {
1864 			if (p + 5 + SMB_STATUS_SIZE >
1865 			    (char*)server->packet + server->packet_size) {
1866 				result = -ENAMETOOLONG;
1867 				goto unlock_return;
1868 			}
1869 
1870 			*p++ = 4;
1871 			*p++ = 0;
1872 			*p++ = 5;
1873 			WSET(p, 0, SMB_STATUS_SIZE);
1874 			p += 2;
1875 			memcpy(p, status, SMB_STATUS_SIZE);
1876 			p += SMB_STATUS_SIZE;
1877 		}
1878 
1879 		smb_setup_bcc(server, p);
1880 
1881 		result = smb_request_ok(server, SMBsearch, 1, -1);
1882 		if (result < 0) {
1883 			if ((server->rcls == ERRDOS) &&
1884 			    (server->err  == ERRnofiles))
1885 				break;
1886 			if (smb_retry(server)) {
1887 				ctl->idx = -1;	/* retry */
1888 				result = 0;
1889 			}
1890 			goto unlock_return;
1891 		}
1892 		p = SMB_VWV(server->packet);
1893 		count = WVAL(p, 0);
1894 		if (count <= 0)
1895 			break;
1896 
1897 		result = -EIO;
1898 		bcc = WVAL(p, 2);
1899 		if (bcc != count * SMB_DIRINFO_SIZE + 3)
1900 			goto unlock_return;
1901 		p += 7;
1902 
1903 
1904 		/* Make sure the response fits in the buffer. Fixed sized
1905 		   entries means we don't have to check in the decode loop. */
1906 
1907 		last_status = SMB_BUF(server->packet) + 3 + (count - 1) *
1908 			SMB_DIRINFO_SIZE;
1909 
1910 		if (last_status + SMB_DIRINFO_SIZE >=
1911 		    server->packet + server->packet_size) {
1912 			printk(KERN_ERR "smb_proc_readdir_short: "
1913 			       "last dir entry outside buffer! "
1914 			       "%d@%p  %d@%p\n", SMB_DIRINFO_SIZE, last_status,
1915 			       server->packet_size, server->packet);
1916 			goto unlock_return;
1917 		}
1918 
1919 		/* Read the last entry into the status field. */
1920 		memcpy(status, last_status, SMB_STATUS_SIZE);
1921 
1922 
1923 		/* Now we are ready to parse smb directory entries. */
1924 
1925 		for (i = 0; i < count; i++) {
1926 			p = smb_decode_short_dirent(server, p,
1927 						    &qname, &fattr);
1928 			if (qname.len == 0)
1929 				continue;
1930 			if (entries_seen == 2 && qname.name[0] == '.') {
1931 				if (qname.len == 1)
1932 					continue;
1933 				if (qname.name[1] == '.' && qname.len == 2)
1934 					continue;
1935 			}
1936 			if (!smb_fill_cache(filp, dirent, filldir, ctl,
1937 					    &qname, &fattr))
1938 				;	/* stop reading? */
1939 			entries_seen++;
1940 		}
1941 	}
1942 	result = entries;
1943 
1944 unlock_return:
1945 	smb_unlock_server(server);
1946 	return result;
1947 }
1948 
smb_decode_unix_basic(struct smb_fattr * fattr,struct smb_sb_info * server,char * p)1949 void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p)
1950 {
1951 	/* FIXME: verify nls support. all is sent as utf8? */
1952 
1953 	fattr->f_unix = 1;
1954 	fattr->f_mode = 0;
1955 
1956 	/* FIXME: use the uniqueID from the remote instead? */
1957 	/* 0 L file size in bytes */
1958 	/* 8 L file size on disk in bytes (block count) */
1959 	/* 40 L uid */
1960 	/* 48 L gid */
1961 	/* 56 W file type */
1962 	/* 60 L devmajor */
1963 	/* 68 L devminor */
1964 	/* 76 L unique ID (inode) */
1965 	/* 84 L permissions */
1966 	/* 92 L link count */
1967 
1968 	fattr->f_size = LVAL(p, 0);
1969 	fattr->f_blocks = LVAL(p, 8);
1970 	fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 16));
1971 	fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 24));
1972 	fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 32));
1973 
1974 	if (server->mnt->flags & SMB_MOUNT_UID)
1975 		fattr->f_uid = server->mnt->uid;
1976 	else
1977 		fattr->f_uid = LVAL(p, 40);
1978 
1979 	if (server->mnt->flags & SMB_MOUNT_GID)
1980 		fattr->f_gid = server->mnt->gid;
1981 	else
1982 		fattr->f_gid = LVAL(p, 48);
1983 
1984 	fattr->f_mode |= smb_filetype_to_mode(WVAL(p, 56));
1985 
1986 	if (S_ISBLK(fattr->f_mode) || S_ISCHR(fattr->f_mode)) {
1987 		__u64 major = LVAL(p, 60);
1988 		__u64 minor = LVAL(p, 68);
1989 
1990 		fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff);
1991 	}
1992 
1993 	fattr->f_mode |= LVAL(p, 84);
1994 
1995 	if ( (server->mnt->flags & SMB_MOUNT_DMODE) &&
1996 	     (S_ISDIR(fattr->f_mode)) )
1997 		fattr->f_mode = (server->mnt->dir_mode & S_IRWXUGO) | S_IFDIR;
1998 	else if ( (server->mnt->flags & SMB_MOUNT_FMODE) &&
1999 	          !(S_ISDIR(fattr->f_mode)) )
2000 		fattr->f_mode = (server->mnt->file_mode & S_IRWXUGO) |
2001 				(fattr->f_mode & S_IFMT);
2002 
2003 }
2004 
2005 /*
2006  * Interpret a long filename structure using the specified info level:
2007  *   level 1 for anything below NT1 protocol
2008  *   level 260 for NT1 protocol
2009  *
2010  * qname is filled with the decoded, and possibly translated, name
2011  * fattr receives decoded attributes.
2012  *
2013  * Bugs Noted:
2014  * (1) Win NT 4.0 appends a null byte to names and counts it in the length!
2015  */
2016 static char *
smb_decode_long_dirent(struct smb_sb_info * server,char * p,int level,struct qstr * qname,struct smb_fattr * fattr)2017 smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level,
2018 		       struct qstr *qname, struct smb_fattr *fattr)
2019 {
2020 	char *result;
2021 	unsigned int len = 0;
2022 	int n;
2023 	__u16 date, time;
2024 
2025 	/*
2026 	 * SMB doesn't have a concept of inode numbers ...
2027 	 */
2028 	smb_init_dirent(server, fattr);
2029 	fattr->f_ino = 0;	/* FIXME: do we need this? */
2030 
2031 	switch (level) {
2032 	case 1:
2033 		len = *((unsigned char *) p + 22);
2034 		qname->name = p + 23;
2035 		result = p + 24 + len;
2036 
2037 		date = WVAL(p, 0);
2038 		time = WVAL(p, 2);
2039 		fattr->f_ctime = date_dos2unix(server, date, time);
2040 
2041 		date = WVAL(p, 4);
2042 		time = WVAL(p, 6);
2043 		fattr->f_atime = date_dos2unix(server, date, time);
2044 
2045 		date = WVAL(p, 8);
2046 		time = WVAL(p, 10);
2047 		fattr->f_mtime = date_dos2unix(server, date, time);
2048 		fattr->f_size = DVAL(p, 12);
2049 		/* ULONG allocation size */
2050 		fattr->attr = WVAL(p, 20);
2051 
2052 		VERBOSE("info 1 at %p, len=%d, name=%.*s\n",
2053 			p, len, len, qname->name);
2054 		break;
2055 	case 260:
2056 		result = p + WVAL(p, 0);
2057 		len = DVAL(p, 60);
2058 		if (len > 255) len = 255;
2059 		/* NT4 null terminates */
2060 		qname->name = p + 94;
2061 		if (len && qname->name[len-1] == '\0')
2062 			len--;
2063 
2064 		fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8));
2065 		fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16));
2066 		fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24));
2067 		/* change time (32) */
2068 		fattr->f_size = LVAL(p, 40);
2069 		/* alloc size (48) */
2070 		fattr->attr = DVAL(p, 56);
2071 
2072 		VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
2073 			p, len, len, qname->name);
2074 		break;
2075 	case SMB_FIND_FILE_UNIX:
2076 		result = p + WVAL(p, 0);
2077 		qname->name = p + 108;
2078 
2079 		len = strlen(qname->name);
2080 		/* FIXME: should we check the length?? */
2081 
2082 		p += 8;
2083 		smb_decode_unix_basic(fattr, server, p);
2084 		VERBOSE("info SMB_FIND_FILE_UNIX at %p, len=%d, name=%.*s\n",
2085 			p, len, len, qname->name);
2086 		break;
2087 	default:
2088 		PARANOIA("Unknown info level %d\n", level);
2089 		result = p + WVAL(p, 0);
2090 		goto out;
2091 	}
2092 
2093 	smb_finish_dirent(server, fattr);
2094 
2095 #if 0
2096 	/* FIXME: These only work for ascii chars, and recent smbmount doesn't
2097 	   allow the flag to be set anyway. Remove? */
2098 	switch (server->opt.case_handling) {
2099 	case SMB_CASE_UPPER:
2100 		str_upper(qname->name, len);
2101 		break;
2102 	case SMB_CASE_LOWER:
2103 		str_lower(qname->name, len);
2104 		break;
2105 	default:
2106 		break;
2107 	}
2108 #endif
2109 
2110 	qname->len = 0;
2111 	n = server->ops->convert(server->name_buf, SMB_MAXNAMELEN,
2112 			    qname->name, len,
2113 			    server->remote_nls, server->local_nls);
2114 	if (n > 0) {
2115 		qname->len = n;
2116 		qname->name = server->name_buf;
2117 	}
2118 
2119 out:
2120 	return result;
2121 }
2122 
2123 /* findfirst/findnext flags */
2124 #define SMB_CLOSE_AFTER_FIRST (1<<0)
2125 #define SMB_CLOSE_IF_END (1<<1)
2126 #define SMB_REQUIRE_RESUME_KEY (1<<2)
2127 #define SMB_CONTINUE_BIT (1<<3)
2128 
2129 /*
2130  * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in
2131  * source/libsmb/clilist.c. When looking for smb bugs in the readdir code,
2132  * go there for advise.
2133  *
2134  * Bugs Noted:
2135  * (1) When using Info Level 1 Win NT 4.0 truncates directory listings
2136  * for certain patterns of names and/or lengths. The breakage pattern
2137  * is completely reproducible and can be toggled by the creation of a
2138  * single file. (E.g. echo hi >foo breaks, rm -f foo works.)
2139  */
2140 static int
smb_proc_readdir_long(struct file * filp,void * dirent,filldir_t filldir,struct smb_cache_control * ctl)2141 smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
2142 		      struct smb_cache_control *ctl)
2143 {
2144 	struct dentry *dir = filp->f_dentry;
2145 	struct smb_sb_info *server = server_from_dentry(dir);
2146 	struct qstr qname;
2147 	struct smb_fattr fattr;
2148 
2149 	unsigned char *p, *lastname;
2150 	char *mask, *param = server->temp_buf;
2151 	__u16 command;
2152 	int first, entries_seen;
2153 
2154 	/* Both NT and OS/2 accept info level 1 (but see note below). */
2155 	int info_level = 260;
2156 	const int max_matches = 512;
2157 
2158 	unsigned char *resp_data = NULL;
2159 	unsigned char *resp_param = NULL;
2160 	int resp_data_len = 0;
2161 	int resp_param_len = 0;
2162 	int ff_searchcount = 0;
2163 	int ff_eos = 0;
2164 	int ff_lastname = 0;
2165 	int ff_dir_handle = 0;
2166 	int loop_count = 0;
2167 	int mask_len, i, result;
2168 	static struct qstr star = { "*", 1, 0 };
2169 
2170 	/*
2171 	 * use info level 1 for older servers that don't do 260
2172 	 */
2173 	if (server->opt.capabilities & SMB_CAP_UNIX)
2174 		info_level = SMB_FIND_FILE_UNIX;
2175 	else if (server->opt.protocol < SMB_PROTOCOL_NT1)
2176 		info_level = 1;
2177 
2178 	smb_lock_server(server);
2179 
2180 	/*
2181 	 * Encode the initial path
2182 	 */
2183 	mask = param + 12;
2184 
2185 	mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
2186 	if (mask_len < 0) {
2187 		result = mask_len;
2188 		goto unlock_return;
2189 	}
2190 	mask_len--;	/* mask_len is strlen, not #bytes */
2191 	first = 1;
2192 	VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);
2193 
2194 	result = 0;
2195 	entries_seen = 2;
2196 	ff_eos = 0;
2197 
2198 	while (ff_eos == 0) {
2199 		loop_count += 1;
2200 		if (loop_count > 10) {
2201 			printk(KERN_WARNING "smb_proc_readdir_long: "
2202 			       "Looping in FIND_NEXT??\n");
2203 			result = -EIO;
2204 			break;
2205 		}
2206 
2207 		if (first != 0) {
2208 			command = TRANSACT2_FINDFIRST;
2209 			WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
2210 			WSET(param, 2, max_matches);	/* max count */
2211 			WSET(param, 4, SMB_CLOSE_IF_END);
2212 			WSET(param, 6, info_level);
2213 			DSET(param, 8, 0);
2214 		} else {
2215 			command = TRANSACT2_FINDNEXT;
2216 
2217 			VERBOSE("handle=0x%X, lastname=%d, mask=%s\n",
2218 				ff_dir_handle, ff_lastname, mask);
2219 
2220 			WSET(param, 0, ff_dir_handle);	/* search handle */
2221 			WSET(param, 2, max_matches);	/* max count */
2222 			WSET(param, 4, info_level);
2223 			DSET(param, 6, 0);
2224 			WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
2225 		}
2226 
2227 		result = smb_trans2_request(server, command,
2228 					    0, NULL, 12 + mask_len + 1, param,
2229 					    &resp_data_len, &resp_data,
2230 					    &resp_param_len, &resp_param);
2231 
2232 		if (result < 0) {
2233 			if (smb_retry(server)) {
2234 				PARANOIA("error=%d, retrying\n", result);
2235 				ctl->idx = -1;	/* retry */
2236 				result = 0;
2237 				goto unlock_return;
2238 			}
2239 			PARANOIA("error=%d, breaking\n", result);
2240 			break;
2241 		}
2242 
2243 		if (server->rcls == ERRSRV && server->err == ERRerror) {
2244 			/* a damn Win95 bug - sometimes it clags if you
2245 			   ask it too fast */
2246 			current->state = TASK_INTERRUPTIBLE;
2247 			schedule_timeout(HZ/5);
2248 			continue;
2249                 }
2250 
2251 		if (server->rcls != 0) {
2252 			result = smb_errno(server);
2253 			PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",
2254 				 mask, result, server->rcls, server->err);
2255 			break;
2256 		}
2257 
2258 		/* parse out some important return info */
2259 		if (first != 0) {
2260 			ff_dir_handle = WVAL(resp_param, 0);
2261 			ff_searchcount = WVAL(resp_param, 2);
2262 			ff_eos = WVAL(resp_param, 4);
2263 			ff_lastname = WVAL(resp_param, 8);
2264 		} else {
2265 			ff_searchcount = WVAL(resp_param, 0);
2266 			ff_eos = WVAL(resp_param, 2);
2267 			ff_lastname = WVAL(resp_param, 6);
2268 		}
2269 
2270 		if (ff_searchcount == 0)
2271 			break;
2272 
2273 		/*
2274 		 * We might need the lastname for continuations.
2275 		 *
2276 		 * Note that some servers (win95?) point to the filename and
2277 		 * others (NT4, Samba using NT1) to the dir entry. We assume
2278 		 * here that those who do not point to a filename do not need
2279 		 * this info to continue the listing.
2280 		 *
2281 		 * OS/2 needs this and talks infolevel 1
2282 		 * NetApps want lastname with infolevel 260
2283 		 * win2k want lastname with infolevel 260, and points to
2284 		 *       the record not to the name.
2285 		 * Samba+CifsUnixExt doesn't need lastname.
2286 		 *
2287 		 * All are happy if we return the data they point to. So we do.
2288 		 */
2289 		mask_len = 0;
2290 		if (info_level != SMB_FIND_FILE_UNIX &&
2291 		    ff_lastname > 0 && ff_lastname < resp_data_len) {
2292 			lastname = resp_data + ff_lastname;
2293 
2294 			switch (info_level) {
2295 			case 260:
2296 				mask_len = resp_data_len - ff_lastname;
2297 				break;
2298 			case 1:
2299 				/* lastname points to a length byte */
2300 				mask_len = *lastname++;
2301 				if (ff_lastname + 1 + mask_len > resp_data_len)
2302 					mask_len = resp_data_len - ff_lastname - 1;
2303 				break;
2304 			}
2305 
2306 			/*
2307 			 * Update the mask string for the next message.
2308 			 */
2309 			if (mask_len < 0)
2310 				mask_len = 0;
2311 			if (mask_len > 255)
2312 				mask_len = 255;
2313 			if (mask_len)
2314 				strncpy(mask, lastname, mask_len);
2315 		}
2316 		mask_len = strnlen(mask, mask_len);
2317 		VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n",
2318 			mask_len, ff_lastname, resp_data_len, mask_len, mask);
2319 
2320 		/* Now we are ready to parse smb directory entries. */
2321 
2322 		/* point to the data bytes */
2323 		p = resp_data;
2324 		for (i = 0; i < ff_searchcount; i++) {
2325 			/* make sure we stay within the buffer */
2326 			if (p >= resp_data + resp_data_len) {
2327 				printk(KERN_ERR "smb_proc_readdir_long: "
2328 				       "dirent pointer outside buffer! "
2329 				       "%p  %d@%p  %d@%p\n",
2330 				       p, resp_data_len, resp_data,
2331 				       server->packet_size, server->packet);
2332 				result = -EIO; /* always a comm. error? */
2333 				goto unlock_return;
2334 			}
2335 
2336 			p = smb_decode_long_dirent(server, p, info_level,
2337 						   &qname, &fattr);
2338 			if (qname.len == 0)
2339 				continue;
2340 
2341 			/* ignore . and .. from the server */
2342 			if (entries_seen == 2 && qname.name[0] == '.') {
2343 				if (qname.len == 1)
2344 					continue;
2345 				if (qname.name[1] == '.' && qname.len == 2)
2346 					continue;
2347 			}
2348 
2349 			if (!smb_fill_cache(filp, dirent, filldir, ctl,
2350 					    &qname, &fattr))
2351 				;	/* stop reading? */
2352 			entries_seen++;
2353 		}
2354 
2355 		VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos);
2356 
2357 		first = 0;
2358 		loop_count = 0;
2359 	}
2360 
2361 unlock_return:
2362 	smb_unlock_server(server);
2363 	return result;
2364 }
2365 
2366 /*
2367  * This version uses the trans2 TRANSACT2_FINDFIRST message
2368  * to get the attribute data.
2369  * Note: called with the server locked.
2370  *
2371  * Bugs Noted:
2372  */
2373 static int
smb_proc_getattr_ff(struct smb_sb_info * server,struct dentry * dentry,struct smb_fattr * fattr)2374 smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
2375 			struct smb_fattr *fattr)
2376 {
2377 	char *param = server->temp_buf, *mask = param + 12;
2378 	__u16 date, time;
2379 	unsigned char *resp_data = NULL;
2380 	unsigned char *resp_param = NULL;
2381 	int resp_data_len = 0;
2382 	int resp_param_len = 0;
2383 	int mask_len, result;
2384 
2385 retry:
2386 	mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry, NULL);
2387 	if (mask_len < 0) {
2388 		result = mask_len;
2389 		goto out;
2390 	}
2391 	VERBOSE("name=%s, len=%d\n", mask, mask_len);
2392 	WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
2393 	WSET(param, 2, 1);	/* max count */
2394 	WSET(param, 4, 1);	/* close after this call */
2395 	WSET(param, 6, 1);	/* info_level */
2396 	DSET(param, 8, 0);
2397 
2398 	result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
2399 				    0, NULL, 12 + mask_len, param,
2400 				    &resp_data_len, &resp_data,
2401 				    &resp_param_len, &resp_param);
2402 	if (result < 0)
2403 	{
2404 		if (smb_retry(server))
2405 			goto retry;
2406 		goto out;
2407 	}
2408 	if (server->rcls != 0)
2409 	{
2410 		result = smb_errno(server);
2411 #ifdef SMBFS_PARANOIA
2412 		if (result != -ENOENT)
2413 			PARANOIA("error for %s, rcls=%d, err=%d\n",
2414 				 mask, server->rcls, server->err);
2415 #endif
2416 		goto out;
2417 	}
2418 	/* Make sure we got enough data ... */
2419 	result = -EINVAL;
2420 	if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)
2421 	{
2422 		PARANOIA("bad result for %s, len=%d, count=%d\n",
2423 			 mask, resp_data_len, WVAL(resp_param, 2));
2424 		goto out;
2425 	}
2426 
2427 	/*
2428 	 * Decode the response into the fattr ...
2429 	 */
2430 	date = WVAL(resp_data, 0);
2431 	time = WVAL(resp_data, 2);
2432 	fattr->f_ctime = date_dos2unix(server, date, time);
2433 
2434 	date = WVAL(resp_data, 4);
2435 	time = WVAL(resp_data, 6);
2436 	fattr->f_atime = date_dos2unix(server, date, time);
2437 
2438 	date = WVAL(resp_data, 8);
2439 	time = WVAL(resp_data, 10);
2440 	fattr->f_mtime = date_dos2unix(server, date, time);
2441 	VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n",
2442 		mask, date, time, fattr->f_mtime);
2443 	fattr->f_size = DVAL(resp_data, 12);
2444 	/* ULONG allocation size */
2445 	fattr->attr = WVAL(resp_data, 20);
2446 	result = 0;
2447 
2448 out:
2449 	return result;
2450 }
2451 
2452 /*
2453  * Note: called with the server locked.
2454  */
2455 static int
smb_proc_getattr_core(struct smb_sb_info * server,struct dentry * dir,struct smb_fattr * fattr)2456 smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
2457 		      struct smb_fattr *fattr)
2458 {
2459 	int result;
2460 	char *p;
2461 
2462       retry:
2463 	p = smb_setup_header(server, SMBgetatr, 0, 0);
2464 	result = smb_simple_encode_path(server, &p, dir, NULL);
2465 	if (result < 0)
2466 		goto out;
2467 	smb_setup_bcc(server, p);
2468 
2469 	if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)
2470 	{
2471 		if (smb_retry(server))
2472 			goto retry;
2473 		goto out;
2474 	}
2475 	fattr->attr    = WVAL(server->packet, smb_vwv0);
2476 	fattr->f_mtime = local2utc(server, DVAL(server->packet, smb_vwv1));
2477 	fattr->f_size  = DVAL(server->packet, smb_vwv3);
2478 	fattr->f_ctime = fattr->f_mtime;
2479 	fattr->f_atime = fattr->f_mtime;
2480 #ifdef SMBFS_DEBUG_TIMESTAMP
2481 	printk("getattr_core: %s/%s, mtime=%ld\n",
2482 	       DENTRY_PATH(dir), fattr->f_mtime);
2483 #endif
2484 	result = 0;
2485 
2486 out:
2487 	return result;
2488 }
2489 
2490 /*
2491  * Note: called with the server locked.
2492  */
2493 static int
smb_proc_getattr_trans2_all(struct smb_sb_info * server,struct dentry * dir,struct smb_fattr * attr)2494 smb_proc_getattr_trans2_all(struct smb_sb_info *server, struct dentry *dir,
2495 			    struct smb_fattr *attr)
2496 {
2497 	char *p, *param = server->temp_buf;
2498 	unsigned char *resp_data = NULL;
2499 	unsigned char *resp_param = NULL;
2500 	int resp_data_len = 0;
2501 	int resp_param_len = 0;
2502 	int result;
2503 
2504       retry:
2505 	WSET(param, 0, SMB_QUERY_FILE_ALL_INFO);
2506 	DSET(param, 2, 0);
2507 	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
2508 	if (result < 0)
2509 		goto out;
2510 	p = param + 6 + result;
2511 
2512 	result = smb_trans2_request(server, TRANSACT2_QPATHINFO,
2513 				    0, NULL, p - param, param,
2514 				    &resp_data_len, &resp_data,
2515 				    &resp_param_len, &resp_param);
2516 	if (result < 0) {
2517 		if (smb_retry(server))
2518 			goto retry;
2519 		goto out;
2520 	}
2521 	if (server->rcls != 0) {
2522 		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
2523 			&param[6], result, server->rcls, server->err);
2524 		result = smb_errno(server);
2525 		goto out;
2526 	}
2527 
2528 	result = -ENOENT;
2529 	if (resp_data_len < 56) {
2530 		PARANOIA("not enough data for %s, len=%d\n",
2531 			 &param[6], resp_data_len);
2532 		goto out;
2533 	}
2534 
2535 	attr->f_ctime = smb_ntutc2unixutc(LVAL(resp_data, 0));
2536 	attr->f_atime = smb_ntutc2unixutc(LVAL(resp_data, 8));
2537 	attr->f_mtime = smb_ntutc2unixutc(LVAL(resp_data, 16));
2538 	/* change (24) */
2539 	attr->attr = WVAL(resp_data, 32);
2540 	/* pad? (34) */
2541 	/* allocated size (40) */
2542 	attr->f_size = LVAL(resp_data, 48);
2543 	result = 0;
2544 
2545 out:
2546 	return result;
2547 }
2548 
2549 /*
2550  * Note: called with the server locked.
2551  *
2552  * Bugs Noted:
2553  * (1) Win 95 swaps the date and time fields in the standard info level.
2554  */
2555 static int
smb_proc_getattr_trans2_std(struct smb_sb_info * server,struct dentry * dir,struct smb_fattr * attr)2556 smb_proc_getattr_trans2_std(struct smb_sb_info *server, struct dentry *dir,
2557 			struct smb_fattr *attr)
2558 {
2559 	char *p, *param = server->temp_buf;
2560 	__u16 date, time;
2561 	int off_date = 0, off_time = 2;
2562 	unsigned char *resp_data = NULL;
2563 	unsigned char *resp_param = NULL;
2564 	int resp_data_len = 0;
2565 	int resp_param_len = 0;
2566 	int result;
2567 
2568       retry:
2569 	WSET(param, 0, SMB_INFO_STANDARD);
2570 	DSET(param, 2, 0);
2571 	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
2572 	if (result < 0)
2573 		goto out;
2574 	p = param + 6 + result;
2575 
2576 	result = smb_trans2_request(server, TRANSACT2_QPATHINFO,
2577 				    0, NULL, p - param, param,
2578 				    &resp_data_len, &resp_data,
2579 				    &resp_param_len, &resp_param);
2580 	if (result < 0)
2581 	{
2582 		if (smb_retry(server))
2583 			goto retry;
2584 		goto out;
2585 	}
2586 	if (server->rcls != 0)
2587 	{
2588 		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
2589 			&param[6], result, server->rcls, server->err);
2590 		result = smb_errno(server);
2591 		goto out;
2592 	}
2593 
2594 	result = -ENOENT;
2595 	if (resp_data_len < 22)
2596 	{
2597 		PARANOIA("not enough data for %s, len=%d\n",
2598 			 &param[6], resp_data_len);
2599 		goto out;
2600 	}
2601 
2602 	/*
2603 	 * Kludge alert: Win 95 swaps the date and time field,
2604 	 * contrary to the CIFS docs and Win NT practice.
2605 	 */
2606 	if (server->mnt->flags & SMB_MOUNT_WIN95) {
2607 		off_date = 2;
2608 		off_time = 0;
2609 	}
2610 	date = WVAL(resp_data, off_date);
2611 	time = WVAL(resp_data, off_time);
2612 	attr->f_ctime = date_dos2unix(server, date, time);
2613 
2614 	date = WVAL(resp_data, 4 + off_date);
2615 	time = WVAL(resp_data, 4 + off_time);
2616 	attr->f_atime = date_dos2unix(server, date, time);
2617 
2618 	date = WVAL(resp_data, 8 + off_date);
2619 	time = WVAL(resp_data, 8 + off_time);
2620 	attr->f_mtime = date_dos2unix(server, date, time);
2621 #ifdef SMBFS_DEBUG_TIMESTAMP
2622 	printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
2623 	       DENTRY_PATH(dir), date, time, attr->f_mtime);
2624 #endif
2625 	attr->f_size = DVAL(resp_data, 12);
2626 	attr->attr = WVAL(resp_data, 20);
2627 	result = 0;
2628 
2629 out:
2630 	return result;
2631 }
2632 
2633 static int
smb_proc_getattr_95(struct smb_sb_info * server,struct dentry * dir,struct smb_fattr * attr)2634 smb_proc_getattr_95(struct smb_sb_info *server, struct dentry *dir,
2635 		    struct smb_fattr *attr)
2636 {
2637 	struct inode *inode = dir->d_inode;
2638 	int result;
2639 
2640 retry:
2641 	result = smb_proc_getattr_trans2_std(server, dir, attr);
2642 	if (result < 0) {
2643 		if (server->rcls == ERRSRV && server->err == ERRerror) {
2644 			/* a damn Win95 bug - sometimes it clags if you
2645 			   ask it too fast */
2646 			current->state = TASK_INTERRUPTIBLE;
2647 			schedule_timeout(HZ/5);
2648 			goto retry;
2649 		}
2650 		goto out;
2651 	}
2652 
2653 	/*
2654 	 * None of the other getattr versions here can make win9x
2655 	 * return the right filesize if there are changes made to an
2656 	 * open file.  A seek-to-end does return the right size, but
2657 	 * we only need to do that on files we have written.
2658 	 */
2659 	if (inode && inode->u.smbfs_i.flags & SMB_F_LOCALWRITE &&
2660 	    smb_is_open(inode))
2661 	{
2662 		__u16 fileid = inode->u.smbfs_i.fileid;
2663 		attr->f_size = smb_proc_seek(server, fileid, 2, 0);
2664 	}
2665 
2666 out:
2667 	return result;
2668 }
2669 
2670 /*
2671  * Note: called with the server locked.
2672  */
2673 static int
smb_proc_getattr_unix(struct smb_sb_info * server,struct dentry * dir,struct smb_fattr * attr)2674 smb_proc_getattr_unix(struct smb_sb_info *server, struct dentry *dir,
2675 		      struct smb_fattr *attr)
2676 {
2677 	char *p, *param = server->temp_buf;
2678 	unsigned char *resp_data = NULL;
2679 	unsigned char *resp_param = NULL;
2680 	int resp_data_len = 0;
2681 	int resp_param_len = 0;
2682 	int result;
2683 
2684       retry:
2685 	WSET(param, 0, SMB_QUERY_FILE_UNIX_BASIC);
2686 	DSET(param, 2, 0);
2687 	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
2688 	if (result < 0)
2689 		goto out;
2690 	p = param + 6 + result;
2691 
2692 	result = smb_trans2_request(server, TRANSACT2_QPATHINFO,
2693 				    0, NULL, p - param, param,
2694 				    &resp_data_len, &resp_data,
2695 				    &resp_param_len, &resp_param);
2696 	if (result < 0) {
2697 		if (smb_retry(server))
2698 			goto retry;
2699 		goto out;
2700 	}
2701 	if (server->rcls != 0) {
2702 		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
2703 			&param[6], result, server->rcls, server->err);
2704 		result = smb_errno(server);
2705 		goto out;
2706 	}
2707 
2708 	smb_decode_unix_basic(attr, server, resp_data);
2709 	result = 0;
2710 
2711 out:
2712 	return result;
2713 }
2714 
2715 static int
smb_proc_getattr_null(struct smb_sb_info * server,struct dentry * dir,struct smb_fattr * attr)2716 smb_proc_getattr_null(struct smb_sb_info *server, struct dentry *dir,
2717 		      struct smb_fattr *attr)
2718 {
2719 	return -EIO;
2720 }
2721 
2722 int
smb_proc_getattr(struct dentry * dir,struct smb_fattr * fattr)2723 smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
2724 {
2725 	struct smb_sb_info *server = server_from_dentry(dir);
2726 	int result;
2727 
2728 	smb_lock_server(server);
2729 	smb_init_dirent(server, fattr);
2730 	result = server->ops->getattr(server, dir, fattr);
2731 	smb_finish_dirent(server, fattr);
2732 	smb_unlock_server(server);
2733 	return result;
2734 }
2735 
2736 
2737 /*
2738  * Called with the server locked. Because of bugs in the
2739  * core protocol, we use this only to set attributes. See
2740  * smb_proc_settime() below for timestamp handling.
2741  *
2742  * Bugs Noted:
2743  * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail
2744  * with an undocumented error (ERRDOS code 50). Setting
2745  * mtime to 0 allows the attributes to be set.
2746  * (2) The extra parameters following the name string aren't
2747  * in the CIFS docs, but seem to be necessary for operation.
2748  */
2749 static int
smb_proc_setattr_core(struct smb_sb_info * server,struct dentry * dentry,__u16 attr)2750 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
2751 		      __u16 attr)
2752 {
2753 	char *p;
2754 	int result;
2755 
2756       retry:
2757 	p = smb_setup_header(server, SMBsetatr, 8, 0);
2758 	WSET(server->packet, smb_vwv0, attr);
2759 	DSET(server->packet, smb_vwv1, 0); /* mtime */
2760 	WSET(server->packet, smb_vwv3, 0); /* reserved values */
2761 	WSET(server->packet, smb_vwv4, 0);
2762 	WSET(server->packet, smb_vwv5, 0);
2763 	WSET(server->packet, smb_vwv6, 0);
2764 	WSET(server->packet, smb_vwv7, 0);
2765 	result = smb_simple_encode_path(server, &p, dentry, NULL);
2766 	if (result < 0)
2767 		goto out;
2768 	if (p + 2 > (char *)server->packet + server->packet_size) {
2769 		result = -ENAMETOOLONG;
2770 		goto out;
2771 	}
2772 	*p++ = 4;
2773 	*p++ = 0;
2774 	smb_setup_bcc(server, p);
2775 
2776 	result = smb_request_ok(server, SMBsetatr, 0, 0);
2777 	if (result < 0) {
2778 		if (smb_retry(server))
2779 			goto retry;
2780 		goto out;
2781 	}
2782 	result = 0;
2783 out:
2784 	return result;
2785 }
2786 
2787 /*
2788  * Because of bugs in the trans2 setattr messages, we must set
2789  * attributes and timestamps separately. The core SMBsetatr
2790  * message seems to be the only reliable way to set attributes.
2791  */
2792 int
smb_proc_setattr(struct dentry * dir,struct smb_fattr * fattr)2793 smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr)
2794 {
2795 	struct smb_sb_info *server = server_from_dentry(dir);
2796 	int result;
2797 
2798 	VERBOSE("setting %s/%s, open=%d\n",
2799 		DENTRY_PATH(dir), smb_is_open(dir->d_inode));
2800 	smb_lock_server(server);
2801 	result = smb_proc_setattr_core(server, dir, fattr->attr);
2802 	smb_unlock_server(server);
2803 	return result;
2804 }
2805 
2806 /*
2807  * Called with the server locked. Sets the timestamps for an
2808  * file open with write permissions.
2809  */
2810 static int
smb_proc_setattr_ext(struct smb_sb_info * server,struct inode * inode,struct smb_fattr * fattr)2811 smb_proc_setattr_ext(struct smb_sb_info *server,
2812 		      struct inode *inode, struct smb_fattr *fattr)
2813 {
2814 	__u16 date, time;
2815 	int result;
2816 
2817       retry:
2818 	smb_setup_header(server, SMBsetattrE, 7, 0);
2819 	WSET(server->packet, smb_vwv0, inode->u.smbfs_i.fileid);
2820 	/* We don't change the creation time */
2821 	WSET(server->packet, smb_vwv1, 0);
2822 	WSET(server->packet, smb_vwv2, 0);
2823 	date_unix2dos(server, fattr->f_atime, &date, &time);
2824 	WSET(server->packet, smb_vwv3, date);
2825 	WSET(server->packet, smb_vwv4, time);
2826 	date_unix2dos(server, fattr->f_mtime, &date, &time);
2827 	WSET(server->packet, smb_vwv5, date);
2828 	WSET(server->packet, smb_vwv6, time);
2829 #ifdef SMBFS_DEBUG_TIMESTAMP
2830 	printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n",
2831 	       date, time, fattr->f_mtime);
2832 #endif
2833 
2834 	result = smb_request_ok(server, SMBsetattrE, 0, 0);
2835 	if (result < 0) {
2836 		if (smb_retry(server))
2837 			goto retry;
2838 		goto out;
2839 	}
2840 	result = 0;
2841 out:
2842 	return result;
2843 }
2844 
2845 /*
2846  * Note: called with the server locked.
2847  *
2848  * Bugs Noted:
2849  * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't
2850  * set the file's attribute flags.
2851  */
2852 static int
smb_proc_setattr_trans2(struct smb_sb_info * server,struct dentry * dir,struct smb_fattr * fattr)2853 smb_proc_setattr_trans2(struct smb_sb_info *server,
2854 			struct dentry *dir, struct smb_fattr *fattr)
2855 {
2856 	__u16 date, time;
2857 	char *p, *param = server->temp_buf;
2858 	unsigned char *resp_data = NULL;
2859 	unsigned char *resp_param = NULL;
2860 	int resp_data_len = 0;
2861 	int resp_param_len = 0;
2862 	int result;
2863 	char data[26];
2864 
2865       retry:
2866 	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */
2867 	DSET(param, 2, 0);
2868 	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
2869 	if (result < 0)
2870 		goto out;
2871 	p = param + 6 + result;
2872 
2873 	WSET(data, 0, 0); /* creation time */
2874 	WSET(data, 2, 0);
2875 	date_unix2dos(server, fattr->f_atime, &date, &time);
2876 	WSET(data, 4, date);
2877 	WSET(data, 6, time);
2878 	date_unix2dos(server, fattr->f_mtime, &date, &time);
2879 	WSET(data, 8, date);
2880 	WSET(data, 10, time);
2881 #ifdef SMBFS_DEBUG_TIMESTAMP
2882 	printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
2883 	       DENTRY_PATH(dir), date, time, fattr->f_mtime);
2884 #endif
2885 	DSET(data, 12, 0); /* size */
2886 	DSET(data, 16, 0); /* blksize */
2887 	WSET(data, 20, 0); /* attr */
2888 	DSET(data, 22, 0); /* ULONG EA size */
2889 
2890 	result = smb_trans2_request(server, TRANSACT2_SETPATHINFO,
2891 				    26, data, p - param, param,
2892 				    &resp_data_len, &resp_data,
2893 				    &resp_param_len, &resp_param);
2894 	if (result < 0)
2895 	{
2896 		if (smb_retry(server))
2897 			goto retry;
2898 		goto out;
2899 	}
2900 	result = 0;
2901 	if (server->rcls != 0)
2902 		result = smb_errno(server);
2903 
2904 out:
2905 	return result;
2906 }
2907 
2908 /*
2909  * ATTR_MODE      0x001
2910  * ATTR_UID       0x002
2911  * ATTR_GID       0x004
2912  * ATTR_SIZE      0x008
2913  * ATTR_ATIME     0x010
2914  * ATTR_MTIME     0x020
2915  * ATTR_CTIME     0x040
2916  * ATTR_ATIME_SET 0x080
2917  * ATTR_MTIME_SET 0x100
2918  * ATTR_FORCE     0x200
2919  * ATTR_ATTR_FLAG 0x400
2920  *
2921  * major/minor should only be set by mknod.
2922  */
2923 int
smb_proc_setattr_unix(struct dentry * dentry,struct iattr * attr,unsigned int major,unsigned int minor)2924 smb_proc_setattr_unix(struct dentry *dentry, struct iattr *attr,
2925 		      unsigned int major, unsigned int minor)
2926 {
2927 	struct smb_sb_info *server = server_from_dentry(dentry);
2928 	u64 nttime;
2929 	char *p, *param;
2930 	unsigned char *resp_data = NULL;
2931 	unsigned char *resp_param = NULL;
2932 	int resp_data_len = 0;
2933 	int resp_param_len = 0;
2934 	int result;
2935 	char data[100];
2936 
2937 	smb_lock_server(server);
2938 	param = server->temp_buf;
2939 
2940 	DEBUG1("valid flags = 0x%04x\n", attr->ia_valid);
2941 
2942 retry:
2943 	WSET(param, 0, SMB_SET_FILE_UNIX_BASIC);
2944 	DSET(param, 2, 0);
2945 	result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, dentry, NULL);
2946 	if (result < 0)
2947 		goto out;
2948 	p = param + 6 + result;
2949 
2950 	/* 0 L file size in bytes */
2951 	/* 8 L file size on disk in bytes (block count) */
2952 	/* 40 L uid */
2953 	/* 48 L gid */
2954 	/* 56 W file type enum */
2955 	/* 60 L devmajor */
2956 	/* 68 L devminor */
2957 	/* 76 L unique ID (inode) */
2958 	/* 84 L permissions */
2959 	/* 92 L link count */
2960 	LSET(data, 0, SMB_SIZE_NO_CHANGE);
2961 	LSET(data, 8, SMB_SIZE_NO_CHANGE);
2962 	LSET(data, 16, SMB_TIME_NO_CHANGE);
2963 	LSET(data, 24, SMB_TIME_NO_CHANGE);
2964 	LSET(data, 32, SMB_TIME_NO_CHANGE);
2965 	LSET(data, 40, SMB_UID_NO_CHANGE);
2966 	LSET(data, 48, SMB_GID_NO_CHANGE);
2967 	DSET(data, 56, smb_filetype_from_mode(attr->ia_mode));
2968 	LSET(data, 60, major);
2969 	LSET(data, 68, minor);
2970 	LSET(data, 76, 0);
2971 	LSET(data, 84, SMB_MODE_NO_CHANGE);
2972 	LSET(data, 92, 0);
2973 
2974 	if (attr->ia_valid & ATTR_SIZE) {
2975 		LSET(data, 0, attr->ia_size);
2976 		LSET(data, 8, 0); /* can't set anyway */
2977 	}
2978 
2979 	/*
2980 	 * FIXME: check the conversion function it the correct one
2981 	 *
2982 	 * we can't set ctime but we might as well pass this to the server
2983 	 * and let it ignore it.
2984 	 */
2985 	if (attr->ia_valid & ATTR_CTIME) {
2986 		nttime = smb_unixutc2ntutc(attr->ia_ctime);
2987 		LSET(data, 16, nttime);
2988 	}
2989 	if (attr->ia_valid & ATTR_ATIME) {
2990 		nttime = smb_unixutc2ntutc(attr->ia_atime);
2991 		LSET(data, 24, nttime);
2992 	}
2993 	if (attr->ia_valid & ATTR_MTIME) {
2994 		nttime = smb_unixutc2ntutc(attr->ia_mtime);
2995 		LSET(data, 32, nttime);
2996 	}
2997 
2998 	if (attr->ia_valid & ATTR_UID) {
2999 		LSET(data, 40, attr->ia_uid);
3000 	}
3001 	if (attr->ia_valid & ATTR_GID) {
3002 		LSET(data, 48, attr->ia_gid);
3003 	}
3004 
3005 	if (attr->ia_valid & ATTR_MODE) {
3006 		LSET(data, 84, attr->ia_mode);
3007 	}
3008 
3009 	result = smb_trans2_request(server, TRANSACT2_SETPATHINFO,
3010 				    sizeof(data), data, p - param, param,
3011 				    &resp_data_len, &resp_data,
3012 				    &resp_param_len, &resp_param);
3013 	if (result < 0)
3014 	{
3015 		if (smb_retry(server))
3016 			goto retry;
3017 		goto out;
3018 	}
3019 	result = 0;
3020 	if (server->rcls != 0)
3021 		result = smb_errno(server);
3022 
3023 out:
3024 	smb_unlock_server(server);
3025 	return result;
3026 }
3027 
3028 /*
3029  * Set the modify and access timestamps for a file.
3030  *
3031  * Incredibly enough, in all of SMB there is no message to allow
3032  * setting both attributes and timestamps at once.
3033  *
3034  * Bugs Noted:
3035  * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message
3036  * with info level 1 (INFO_STANDARD).
3037  * (2) Win 95 seems not to support setting directory timestamps.
3038  * (3) Under the core protocol apparently the only way to set the
3039  * timestamp is to open and close the file.
3040  */
3041 int
smb_proc_settime(struct dentry * dentry,struct smb_fattr * fattr)3042 smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
3043 {
3044 	struct smb_sb_info *server = server_from_dentry(dentry);
3045 	struct inode *inode = dentry->d_inode;
3046 	int result;
3047 
3048 	VERBOSE("setting %s/%s, open=%d\n",
3049 		DENTRY_PATH(dentry), smb_is_open(inode));
3050 
3051 	smb_lock_server(server);
3052 	/* setting the time on a Win95 server fails (tridge) */
3053 	if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 &&
3054 	    !(server->mnt->flags & SMB_MOUNT_WIN95)) {
3055 		if (smb_is_open(inode) &&
3056 		    inode->u.smbfs_i.access != SMB_O_RDONLY)
3057 			result = smb_proc_setattr_ext(server, inode, fattr);
3058 		else
3059 			result = smb_proc_setattr_trans2(server, dentry, fattr);
3060 	} else {
3061 		/*
3062 		 * Fail silently on directories ... timestamp can't be set?
3063 		 */
3064 		result = 0;
3065 		if (S_ISREG(inode->i_mode)) {
3066 			/*
3067 			 * Set the mtime by opening and closing the file.
3068 			 * Note that the file is opened read-only, but this
3069 			 * still allows us to set the date (tridge)
3070 			 */
3071 			result = -EACCES;
3072 			if (!smb_is_open(inode))
3073 				smb_proc_open(server, dentry, SMB_O_RDONLY);
3074 			if (smb_is_open(inode)) {
3075 				inode->i_mtime = fattr->f_mtime;
3076 				result = smb_proc_close_inode(server, inode);
3077 			}
3078 		}
3079 	}
3080 
3081 	smb_unlock_server(server);
3082 	return result;
3083 }
3084 
3085 int
smb_proc_dskattr(struct super_block * sb,struct statfs * attr)3086 smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
3087 {
3088 	struct smb_sb_info *server = &(sb->u.smbfs_sb);
3089 	int result;
3090 	char *p;
3091 	long unit;
3092 
3093 	smb_lock_server(server);
3094 
3095       retry:
3096 	smb_setup_header(server, SMBdskattr, 0, 0);
3097 
3098 	if ((result = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
3099 		if (smb_retry(server))
3100 			goto retry;
3101 		goto out;
3102 	}
3103 	p = SMB_VWV(server->packet);
3104 	unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT;
3105 	attr->f_blocks = WVAL(p, 0) * unit;
3106 	attr->f_bsize  = SMB_ST_BLKSIZE;
3107 	attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit;
3108 	result = 0;
3109 
3110 out:
3111 	smb_unlock_server(server);
3112 	return result;
3113 }
3114 
3115 int
smb_proc_read_link(struct smb_sb_info * server,struct dentry * dentry,char * buffer,int len)3116 smb_proc_read_link(struct smb_sb_info *server, struct dentry *dentry,
3117 		   char *buffer, int len)
3118 {
3119 	char *p, *param = server->temp_buf;
3120 	unsigned char *resp_data = NULL;
3121 	unsigned char *resp_param = NULL;
3122 	int resp_data_len = 0;
3123 	int resp_param_len = 0;
3124 	int result;
3125 
3126 	DEBUG1("readlink of %s/%s\n", DENTRY_PATH(dentry));
3127 
3128 	smb_lock_server(server);
3129   retry:
3130 	WSET(param, 0, SMB_QUERY_FILE_UNIX_LINK);
3131 	DSET(param, 2, 0);
3132 	result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, dentry, NULL);
3133 	if (result < 0)
3134 		goto out;
3135 	p = param + 6 + result;
3136 
3137 	result = smb_trans2_request(server, TRANSACT2_QPATHINFO,
3138 				    0, NULL, p - param, param,
3139 				    &resp_data_len, &resp_data,
3140 				    &resp_param_len, &resp_param);
3141 	DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
3142 		&param[6], result, server->rcls, server->err);
3143 	if (result < 0) {
3144 		if (smb_retry(server))
3145 			goto retry;
3146 		goto out;
3147 	}
3148 	if (server->rcls != 0) {
3149 		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
3150 			&param[6], result, server->rcls, server->err);
3151 		result = smb_errno(server);
3152 		goto out;
3153 	}
3154 
3155 	/* copy data up to the \0 or buffer length */
3156 	result = len;
3157 	if (resp_data_len < len)
3158 		result = resp_data_len;
3159 	strncpy(buffer, resp_data, result);
3160 
3161 out:
3162 	smb_unlock_server(server);
3163 	return result;
3164 }
3165 
3166 
3167 /*
3168  * Create a symlink object called dentry which points to oldpath.
3169  * Samba does not permit dangling links but returns a suitable error message.
3170  */
3171 int
smb_proc_symlink(struct smb_sb_info * server,struct dentry * dentry,const char * oldpath)3172 smb_proc_symlink(struct smb_sb_info *server, struct dentry *dentry,
3173 		 const char *oldpath)
3174 {
3175 	char *p, *param = server->temp_buf;
3176 	unsigned char *resp_data = NULL;
3177 	unsigned char *resp_param = NULL;
3178 	int resp_data_len = 0;
3179 	int resp_param_len = 0;
3180 	int result;
3181 
3182 	smb_lock_server(server);
3183   retry:
3184 	WSET(param, 0, SMB_SET_FILE_UNIX_LINK);
3185 	DSET(param, 2, 0);
3186 	result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, dentry, NULL);
3187 	if (result < 0)
3188 		goto out;
3189 	p = param + 6 + result;
3190 
3191 	result = smb_trans2_request(server, TRANSACT2_SETPATHINFO,
3192 				    strlen(oldpath) + 1,
3193 				    (char *)oldpath, p - param, param,
3194 				    &resp_data_len, &resp_data,
3195 				    &resp_param_len, &resp_param);
3196 	DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
3197 		&param[6], result, server->rcls, server->err);
3198 	if (result < 0) {
3199 		if (smb_retry(server))
3200 			goto retry;
3201 		goto out;
3202 	}
3203 	if (server->rcls != 0) {
3204 		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
3205 			&param[6], result, server->rcls, server->err);
3206 		result = smb_errno(server);
3207 		goto out;
3208 	}
3209 
3210 	result = 0;
3211 
3212 out:
3213 	smb_unlock_server(server);
3214 	return result;
3215 }
3216 
3217 /*
3218  * Create a hard link object called new_dentry which points to dentry.
3219  */
3220 int
smb_proc_link(struct smb_sb_info * server,struct dentry * dentry,struct dentry * new_dentry)3221 smb_proc_link(struct smb_sb_info *server, struct dentry *dentry,
3222 	      struct dentry *new_dentry)
3223 {
3224 	char *p, *param = server->temp_buf;
3225 	unsigned char *resp_data = NULL;
3226 	unsigned char *resp_param = NULL;
3227 	int resp_data_len = 0;
3228 	int resp_param_len = 0;
3229 	int result;
3230 	int newpathlen = 0;
3231 	char newpath[SMB_MAXPATHLEN+1];		/* FIXME: ugh! */
3232 
3233 	smb_lock_server(server);
3234 
3235 	newpathlen = smb_encode_path(server, newpath, SMB_MAXPATHLEN+1, dentry, NULL);
3236 
3237 	DEBUG1("newpathlen = %d newpath=\"%s\"\n", newpathlen, newpath);
3238 retry:
3239 	WSET(param, 0, SMB_SET_FILE_UNIX_HLINK);
3240 	DSET(param, 2, 0);
3241 	result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, new_dentry, NULL);
3242 	if (result < 0)
3243 		goto out;
3244 	p = param + 6 + result;
3245 	DEBUG1("pathlen = %d oldpath=\"%s\"\n", result, param + 6);
3246 
3247 
3248 	result = smb_trans2_request(server, TRANSACT2_SETPATHINFO,
3249 				    newpathlen + 1,
3250 				    (char *)newpath, p - param, param,
3251 				    &resp_data_len, &resp_data,
3252 				    &resp_param_len, &resp_param);
3253 	DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
3254                &param[6], result, server->rcls, server->err);
3255 	if (result < 0) {
3256 		if (smb_retry(server))
3257 			goto retry;
3258 		goto out;
3259 	}
3260 	if (server->rcls != 0) {
3261 		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
3262 			&param[6], result, server->rcls, server->err);
3263 		result = smb_errno(server);
3264 		goto out;
3265 	}
3266 
3267 	result = 0;
3268 
3269 out:
3270 	smb_unlock_server(server);
3271 	return result;
3272 }
3273 
3274 /*
3275  * We are called with the server locked
3276  */
3277 static int
smb_proc_query_cifsunix(struct smb_sb_info * server)3278 smb_proc_query_cifsunix(struct smb_sb_info *server)
3279 {
3280 	char *param = server->temp_buf;
3281 	unsigned char *resp_data = NULL;
3282 	unsigned char *resp_param = NULL;
3283 	int resp_data_len = 0;
3284 	int resp_param_len = 0;
3285 	int result;
3286 	int major, minor;
3287 	u64 caps;
3288 
3289   retry:
3290 	WSET(param, 0, SMB_QUERY_CIFS_UNIX_INFO);
3291 	result = smb_trans2_request(server, TRANSACT2_QFSINFO,
3292 				    0, NULL, 2, param,
3293 				    &resp_data_len, &resp_data,
3294 				    &resp_param_len, &resp_param);
3295 	if (result < 0) {
3296 		if (smb_retry(server))
3297 			goto retry;
3298 		goto out;
3299 	}
3300 
3301 	if (resp_data_len < 12) {
3302 		PARANOIA("Not enough data\n");
3303 		goto out;
3304 	}
3305 
3306 	major = WVAL(resp_data, 0);
3307 	minor = WVAL(resp_data, 2);
3308 	VERBOSE("Server implements CIFS Extensions for UNIX systems v%d.%d\n",
3309 		major, minor);
3310 	/* FIXME: verify that we are ok with this major/minor? */
3311 
3312 	caps = LVAL(resp_data, 4);
3313 	DEBUG1("Server capabilities 0x%016llx\n", caps);
3314 
3315 out:
3316 	return result;
3317 }
3318 
3319 
3320 static void
install_ops(struct smb_ops * dst,struct smb_ops * src)3321 install_ops(struct smb_ops *dst, struct smb_ops *src)
3322 {
3323 	memcpy(dst, src, sizeof(void *) * SMB_OPS_NUM_STATIC);
3324 }
3325 
3326 /* < LANMAN2 */
3327 static struct smb_ops smb_ops_core =
3328 {
3329 	.read           = smb_proc_read,
3330 	.write          = smb_proc_write,
3331 	.readdir        = smb_proc_readdir_short,
3332 	.getattr        = smb_proc_getattr_core,
3333 	.truncate       = smb_proc_trunc32,
3334 };
3335 
3336 /* LANMAN2, OS/2, others? */
3337 static struct smb_ops smb_ops_os2 =
3338 {
3339 	.read           = smb_proc_read,
3340 	.write          = smb_proc_write,
3341 	.readdir        = smb_proc_readdir_long,
3342 	.getattr        = smb_proc_getattr_trans2_std,
3343 	.truncate       = smb_proc_trunc32,
3344 };
3345 
3346 /* Win95, and possibly some NetApp versions too */
3347 static struct smb_ops smb_ops_win95 =
3348 {
3349 	.read           = smb_proc_read,    /* does not support 12word readX */
3350 	.write          = smb_proc_write,
3351 	.readdir        = smb_proc_readdir_long,
3352 	.getattr        = smb_proc_getattr_95,
3353 	.truncate       = smb_proc_trunc95,
3354 };
3355 
3356 /* Samba, NT4 and NT5 */
3357 static struct smb_ops smb_ops_winNT =
3358 {
3359 	.read           = smb_proc_readX,
3360 	.write          = smb_proc_writeX,
3361 	.readdir        = smb_proc_readdir_long,
3362 	.getattr        = smb_proc_getattr_trans2_all,
3363 	.truncate       = smb_proc_trunc64,
3364 };
3365 
3366 /* Samba w/ unix extensions. Others? */
3367 static struct smb_ops smb_ops_unix =
3368 {
3369 	.read           = smb_proc_readX,
3370 	.write          = smb_proc_writeX,
3371 	.readdir        = smb_proc_readdir_long,
3372 	.getattr        = smb_proc_getattr_unix,
3373 	.truncate       = smb_proc_trunc64,
3374 };
3375 
3376 /* Place holder until real ops are in place */
3377 static struct smb_ops smb_ops_null =
3378 {
3379 	.getattr        = smb_proc_getattr_null,
3380 };
3381 
smb_install_null_ops(struct smb_ops * ops)3382 void smb_install_null_ops(struct smb_ops *ops)
3383 {
3384 	install_ops(ops, &smb_ops_null);
3385 }
3386