File: /usr/src/linux/fs/smbfs/proc.c
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
27 #include "smb_debug.h"
28
29
30 /* Features. Undefine if they cause problems, this should perhaps be a
31 config option. */
32 #define SMBFS_POSIX_UNLINK 1
33
34 /* Allow smb_retry to be interrupted. Not sure of the benefit ... */
35 /* #define SMB_RETRY_INTR */
36
37 #define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN)
38 #define SMB_CMD(packet) (*(packet+8))
39 #define SMB_WCT(packet) (*(packet+SMB_HEADER_LEN - 1))
40 #define SMB_BCC(packet) smb_bcc(packet)
41 #define SMB_BUF(packet) ((packet) + SMB_HEADER_LEN + SMB_WCT(packet) * 2 + 2)
42
43 #define SMB_DIRINFO_SIZE 43
44 #define SMB_STATUS_SIZE 21
45
46 static int
47 smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
48 struct smb_fattr *);
49 static int
50 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
51 __u16 attr);
52 static int
53 smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir,
54 struct smb_fattr *fattr);
55
56
57
58 static void
59 str_upper(char *name, int len)
60 {
61 while (len--)
62 {
63 if (*name >= 'a' && *name <= 'z')
64 *name -= ('a' - 'A');
65 name++;
66 }
67 }
68
69 #if 0
70 static void
71 str_lower(char *name, int len)
72 {
73 while (len--)
74 {
75 if (*name >= 'A' && *name <= 'Z')
76 *name += ('a' - 'A');
77 name++;
78 }
79 }
80 #endif
81
82 /* reverse a string inline. This is used by the dircache walking routines */
83 static void reverse_string(char *buf, int len)
84 {
85 char c;
86 char *end = buf+len-1;
87
88 while(buf < end) {
89 c = *buf;
90 *(buf++) = *end;
91 *(end--) = c;
92 }
93 }
94
95 /* no conversion, just a wrapper for memcpy. */
96 static int convert_memcpy(char *output, int olen,
97 const char *input, int ilen,
98 struct nls_table *nls_from,
99 struct nls_table *nls_to)
100 {
101 memcpy(output, input, ilen);
102 return ilen;
103 }
104
105 /* convert from one "codepage" to another (possibly being utf8). */
106 static int convert_cp(char *output, int olen,
107 const char *input, int ilen,
108 struct nls_table *nls_from,
109 struct nls_table *nls_to)
110 {
111 int len = 0;
112 int n;
113 wchar_t ch;
114
115 if (!nls_from || !nls_to) {
116 PARANOIA("nls_from=%p, nls_to=%p\n", nls_from, nls_to);
117 return convert_memcpy(output, olen, input, ilen, NULL, NULL);
118 }
119
120 while (ilen > 0) {
121 /* convert by changing to unicode and back to the new cp */
122 n = nls_from->char2uni((unsigned char *)input, ilen, &ch);
123 if (n < 0)
124 goto out;
125 input += n;
126 ilen -= n;
127
128 n = nls_to->uni2char(ch, output, olen);
129 if (n < 0)
130 goto out;
131 output += n;
132 olen -= n;
133
134 len += n;
135 }
136 out:
137 return len;
138 }
139
140 static int setcodepage(struct smb_sb_info *server,
141 struct nls_table **p, char *name)
142 {
143 struct nls_table *nls;
144
145 if (!name || !*name) {
146 nls = NULL;
147 } else if ( (nls = load_nls(name)) == NULL) {
148 printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name);
149 return -EINVAL;
150 }
151
152 /* if already set, unload the previous one. */
153 if (*p)
154 unload_nls(*p);
155 *p = nls;
156
157 return 0;
158 }
159
160 /* Handles all changes to codepage settings. */
161 int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp)
162 {
163 int n;
164
165 smb_lock_server(server);
166
167 n = setcodepage(server, &server->local_nls, cp->local_name);
168 if (n != 0)
169 goto out;
170 n = setcodepage(server, &server->remote_nls, cp->remote_name);
171 if (n != 0)
172 setcodepage(server, &server->local_nls, NULL);
173
174 out:
175 if (server->local_nls != NULL && server->remote_nls != NULL)
176 server->convert = convert_cp;
177 else
178 server->convert = convert_memcpy;
179
180 smb_unlock_server(server);
181 return n;
182 }
183
184
185 /*****************************************************************************/
186 /* */
187 /* Encoding/Decoding section */
188 /* */
189 /*****************************************************************************/
190
191 __u8 *
192 smb_encode_smb_length(__u8 * p, __u32 len)
193 {
194 *p = 0;
195 *(p+1) = 0;
196 *(p+2) = (len & 0xFF00) >> 8;
197 *(p+3) = (len & 0xFF);
198 if (len > 0xFFFF)
199 {
200 *(p+1) = 1;
201 }
202 return p + 4;
203 }
204
205 /*
206 * smb_build_path: build the path to entry and name storing it in buf.
207 * The path returned will have the trailing '\0'.
208 */
209 static int smb_build_path(struct smb_sb_info *server, char * buf,
210 struct dentry * entry, struct qstr * name)
211 {
212 char *path = buf;
213 int len;
214
215 if (entry == NULL)
216 goto test_name_and_out;
217
218 /*
219 * If IS_ROOT, we have to do no walking at all.
220 */
221 if (IS_ROOT(entry)) {
222 *(path++) = '\\';
223 if (name != NULL)
224 goto name_and_out;
225 goto out;
226 }
227
228 /*
229 * Build the path string walking the tree backward from end to ROOT
230 * and store it in reversed order [see reverse_string()]
231 */
232 for (;;) {
233 if (entry->d_name.len > SMB_MAXNAMELEN)
234 return -ENAMETOOLONG;
235 if (path - buf + entry->d_name.len > SMB_MAXPATHLEN)
236 return -ENAMETOOLONG;
237
238 len = server->convert(path, SMB_MAXNAMELEN,
239 entry->d_name.name, entry->d_name.len,
240 server->local_nls, server->remote_nls);
241 reverse_string(path, len);
242 path += len;
243
244 *(path++) = '\\';
245
246 entry = entry->d_parent;
247
248 if (IS_ROOT(entry))
249 break;
250 }
251
252 reverse_string(buf, path-buf);
253
254 test_name_and_out:
255 if (name != NULL) {
256 *(path++) = '\\';
257 name_and_out:
258 len = server->convert(path, SMB_MAXNAMELEN,
259 name->name, name->len,
260 server->local_nls, server->remote_nls);
261 path += len;
262 }
263 out:
264 *(path++) = '\0';
265 return (path-buf);
266 }
267
268 static int smb_encode_path(struct smb_sb_info *server, char *buf,
269 struct dentry *dir, struct qstr *name)
270 {
271 int result;
272
273 result = smb_build_path(server, buf, dir, name);
274 if (result < 0)
275 goto out;
276 if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS)
277 str_upper(buf, result);
278 out:
279 return result;
280 }
281
282 /* The following are taken directly from msdos-fs */
283
284 /* Linear day numbers of the respective 1sts in non-leap years. */
285
286 static int day_n[] =
287 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
288 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
289
290
291 static time_t
292 utc2local(struct smb_sb_info *server, time_t time)
293 {
294 return time - server->opt.serverzone*60;
295 }
296
297 static time_t
298 local2utc(struct smb_sb_info *server, time_t time)
299 {
300 return time + server->opt.serverzone*60;
301 }
302
303 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
304
305 static time_t
306 date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time)
307 {
308 int month, year;
309 time_t secs;
310
311 month = ((date >> 5) & 15) - 1;
312 year = date >> 9;
313 secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
314 ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
315 month < 2 ? 1 : 0) + 3653);
316 /* days since 1.1.70 plus 80's leap day */
317 return local2utc(server, secs);
318 }
319
320
321 /* Convert linear UNIX date to a MS-DOS time/date pair. */
322
323 static void
324 date_unix2dos(struct smb_sb_info *server,
325 int unix_date, __u16 *date, __u16 *time)
326 {
327 int day, year, nl_day, month;
328
329 unix_date = utc2local(server, unix_date);
330 *time = (unix_date % 60) / 2 +
331 (((unix_date / 60) % 60) << 5) +
332 (((unix_date / 3600) % 24) << 11);
333
334 day = unix_date / 86400 - 3652;
335 year = day / 365;
336 if ((year + 3) / 4 + 365 * year > day)
337 year--;
338 day -= (year + 3) / 4 + 365 * year;
339 if (day == 59 && !(year & 3)) {
340 nl_day = day;
341 month = 2;
342 } else {
343 nl_day = (year & 3) || day <= 59 ? day : day - 1;
344 for (month = 0; month < 12; month++)
345 if (day_n[month] > nl_day)
346 break;
347 }
348 *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9);
349 }
350
351 /* The following are taken from fs/ntfs/util.c */
352
353 /*
354 * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
355 * into Unix UTC (based 1970-01-01, in seconds).
356 *
357 * This is very gross because
358 * 1: We must do 64-bit division on a 32-bit machine
359 * 2: We can't use libgcc for long long operations in the kernel
360 * 3: Floating point math in the kernel would corrupt user data
361 */
362 static time_t
363 smb_ntutc2unixutc(struct smb_sb_info *server, u64 ntutc)
364 {
365 const unsigned int D = 10000000;
366 unsigned int H = (unsigned int)(ntutc >> 32);
367 unsigned int L = (unsigned int)ntutc;
368 unsigned int numerator2;
369 unsigned int lowseconds;
370 unsigned int result;
371
372 /*
373 * It is best to subtract 0x019db1ded53e8000 first.
374 * Then the 1601-based date becomes a 1970-based date.
375 */
376 if (L < (unsigned)0xd53e8000) H--;
377 L -= (unsigned)0xd53e8000;
378 H -= (unsigned)0x019db1de;
379
380 /*
381 * Now divide 64-bit numbers on a 32-bit machine :-)
382 * With the subtraction already done, the result fits in 32 bits.
383 * The numerator fits in 56 bits and the denominator fits
384 * in 24 bits, so we can shift by 8 bits to make this work.
385 */
386
387 numerator2 = (H<<8) | (L>>24);
388 result = (numerator2 / D); /* shifted 24 right!! */
389 lowseconds = result << 24;
390
391 numerator2 = ((numerator2-result*D)<<8) | ((L>>16)&0xff);
392 result = (numerator2 / D); /* shifted 16 right!! */
393 lowseconds |= result << 16;
394
395 numerator2 = ((numerator2-result*D)<<8) | ((L>>8)&0xff);
396 result = (numerator2 / D); /* shifted 8 right!! */
397 lowseconds |= result << 8;
398
399 numerator2 = ((numerator2-result*D)<<8) | (L&0xff);
400 result = (numerator2 / D); /* not shifted */
401 lowseconds |= result;
402
403 return lowseconds;
404 }
405
406 #if 0
407 /* Convert the Unix UTC into NT time */
408 static u64
409 smb_unixutc2ntutc(struct smb_sb_info *server, time_t t)
410 {
411 /* Note: timezone conversion is probably wrong. */
412 return ((utc2local(server, t) + (u64)(369*365+89)*24*3600) * 10000000);
413 }
414 #endif
415
416
417 /*****************************************************************************/
418 /* */
419 /* Support section. */
420 /* */
421 /*****************************************************************************/
422
423 __u32
424 smb_len(__u8 * p)
425 {
426 return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3);
427 }
428
429 static __u16
430 smb_bcc(__u8 * packet)
431 {
432 int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16);
433 return WVAL(packet, pos);
434 }
435
436 /* smb_valid_packet: We check if packet fulfills the basic
437 requirements of a smb packet */
438
439 static int
440 smb_valid_packet(__u8 * packet)
441 {
442 return (packet[4] == 0xff
443 && packet[5] == 'S'
444 && packet[6] == 'M'
445 && packet[7] == 'B'
446 && (smb_len(packet) + 4 == SMB_HEADER_LEN
447 + SMB_WCT(packet) * 2 + SMB_BCC(packet)));
448 }
449
450 /* smb_verify: We check if we got the answer we expected, and if we
451 got enough data. If bcc == -1, we don't care. */
452
453 static int
454 smb_verify(__u8 * packet, int command, int wct, int bcc)
455 {
456 if (SMB_CMD(packet) != command)
457 goto bad_command;
458 if (SMB_WCT(packet) < wct)
459 goto bad_wct;
460 if (bcc != -1 && SMB_BCC(packet) < bcc)
461 goto bad_bcc;
462 return 0;
463
464 bad_command:
465 printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n",
466 command, SMB_CMD(packet));
467 goto fail;
468 bad_wct:
469 printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n",
470 command, wct, SMB_WCT(packet));
471 goto fail;
472 bad_bcc:
473 printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n",
474 command, bcc, SMB_BCC(packet));
475 fail:
476 return -EIO;
477 }
478
479 /*
480 * Returns the maximum read or write size for the "payload". Making all of the
481 * packet fit within the negotiated max_xmit size.
482 *
483 * N.B. Since this value is usually computed before locking the server,
484 * the server's packet size must never be decreased!
485 */
486 static inline int
487 smb_get_xmitsize(struct smb_sb_info *server, int overhead)
488 {
489 return server->opt.max_xmit - overhead;
490 }
491
492 /*
493 * Calculate the maximum read size
494 */
495 int
496 smb_get_rsize(struct smb_sb_info *server)
497 {
498 int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
499 int size = smb_get_xmitsize(server, overhead);
500
501 VERBOSE("packet=%d, xmit=%d, size=%d\n",
502 server->packet_size, server->opt.max_xmit, size);
503
504 return size;
505 }
506
507 /*
508 * Calculate the maximum write size
509 */
510 int
511 smb_get_wsize(struct smb_sb_info *server)
512 {
513 int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
514 int size = smb_get_xmitsize(server, overhead);
515
516 VERBOSE("packet=%d, xmit=%d, size=%d\n",
517 server->packet_size, server->opt.max_xmit, size);
518
519 return size;
520 }
521
522 int
523 smb_errno(struct smb_sb_info *server)
524 {
525 int errcls = server->rcls;
526 int error = server->err;
527 char *class = "Unknown";
528
529 VERBOSE("errcls %d code %d from command 0x%x\n",
530 errcls, error, SMB_CMD(server->packet));
531
532 if (errcls == ERRDOS)
533 switch (error)
534 {
535 case ERRbadfunc:
536 return EINVAL;
537 case ERRbadfile:
538 case ERRbadpath:
539 return ENOENT;
540 case ERRnofids:
541 return EMFILE;
542 case ERRnoaccess:
543 return EACCES;
544 case ERRbadfid:
545 return EBADF;
546 case ERRbadmcb:
547 return EREMOTEIO;
548 case ERRnomem:
549 return ENOMEM;
550 case ERRbadmem:
551 return EFAULT;
552 case ERRbadenv:
553 case ERRbadformat:
554 return EREMOTEIO;
555 case ERRbadaccess:
556 return EACCES;
557 case ERRbaddata:
558 return E2BIG;
559 case ERRbaddrive:
560 return ENXIO;
561 case ERRremcd:
562 return EREMOTEIO;
563 case ERRdiffdevice:
564 return EXDEV;
565 case ERRnofiles: /* Why is this mapped to 0?? */
566 return 0;
567 case ERRbadshare:
568 return ETXTBSY;
569 case ERRlock:
570 return EDEADLK;
571 case ERRfilexists:
572 return EEXIST;
573 case 87: /* should this map to 0?? */
574 return 0; /* Unknown error!! */
575 case 123: /* Invalid name?? e.g. .tmp* */
576 return ENOENT;
577 case 145: /* Win NT 4.0: non-empty directory? */
578 return ENOTEMPTY;
579 /* This next error seems to occur on an mv when
580 * the destination exists */
581 case 183:
582 return EEXIST;
583 default:
584 class = "ERRDOS";
585 goto err_unknown;
586 } else if (errcls == ERRSRV)
587 switch (error)
588 {
589 /* N.B. This is wrong ... EIO ? */
590 case ERRerror:
591 return ENFILE;
592 case ERRbadpw:
593 return EINVAL;
594 case ERRbadtype:
595 return EIO;
596 case ERRaccess:
597 return EACCES;
598 /*
599 * This is a fatal error, as it means the "tree ID"
600 * for this connection is no longer valid. We map
601 * to a special error code and get a new connection.
602 */
603 case ERRinvnid:
604 return EBADSLT;
605 default:
606 class = "ERRSRV";
607 goto err_unknown;
608 } else if (errcls == ERRHRD)
609 switch (error)
610 {
611 case ERRnowrite:
612 return EROFS;
613 case ERRbadunit:
614 return ENODEV;
615 case ERRnotready:
616 return EUCLEAN;
617 case ERRbadcmd:
618 case ERRdata:
619 return EIO;
620 case ERRbadreq:
621 return ERANGE;
622 case ERRbadshare:
623 return ETXTBSY;
624 case ERRlock:
625 return EDEADLK;
626 default:
627 class = "ERRHRD";
628 goto err_unknown;
629 } else if (errcls == ERRCMD)
630 class = "ERRCMD";
631
632 err_unknown:
633 printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
634 class, error, SMB_CMD(server->packet));
635 return EIO;
636 }
637
638 /*
639 * smb_retry: This function should be called when smb_request_ok has
640 * indicated an error. If the error was indicated because the
641 * connection was killed, we try to reconnect. If smb_retry returns 0,
642 * the error was indicated for another reason, so a retry would not be
643 * of any use.
644 * N.B. The server must be locked for this call.
645 */
646 static int
647 smb_retry(struct smb_sb_info *server)
648 {
649 pid_t pid = server->conn_pid;
650 int error, result = 0;
651
652 if (server->state == CONN_VALID || server->state == CONN_RETRYING)
653 goto out;
654
655 smb_close_socket(server);
656
657 if (pid == 0) {
658 printk(KERN_ERR "smb_retry: no connection process\n");
659 server->state = CONN_RETRIED;
660 goto out;
661 }
662
663 /*
664 * Change state so that only one retry per server will be started.
665 */
666 server->state = CONN_RETRYING;
667
668 /*
669 * Note: use the "priv" flag, as a user process may need to reconnect.
670 */
671 error = kill_proc(pid, SIGUSR1, 1);
672 if (error) {
673 /* FIXME: this is fatal */
674 printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error);
675 goto out;
676 }
677 VERBOSE("signalled pid %d, waiting for new connection\n", pid);
678
679 /*
680 * Wait for the new connection.
681 */
682 #ifdef SMB_RETRY_INTR
683 smb_unlock_server(server);
684 interruptible_sleep_on_timeout(&server->wait, 30*HZ);
685 smb_lock_server(server);
686 if (signal_pending(current))
687 printk(KERN_INFO "smb_retry: caught signal\n");
688 #else
689 /*
690 * We don't want to be interrupted. For example, what if 'current'
691 * already has received a signal? sleep_on would terminate immediately
692 * and smbmount would not be able to re-establish connection.
693 *
694 * smbmount should be able to reconnect later, but it can't because
695 * it will get an -EIO on attempts to open the mountpoint!
696 *
697 * FIXME: go back to the interruptable version now that smbmount
698 * can avoid -EIO on the mountpoint when reconnecting?
699 */
700 smb_unlock_server(server);
701 sleep_on_timeout(&server->wait, 30*HZ);
702 smb_lock_server(server);
703 #endif
704
705 /*
706 * Check for a valid connection.
707 */
708 if (server->state == CONN_VALID) {
709 /* This should be changed to VERBOSE, except many smbfs
710 problems is with the userspace daemon not reconnecting. */
711 PARANOIA("successful, new pid=%d, generation=%d\n",
712 server->conn_pid, server->generation);
713 result = 1;
714 } else if (server->state == CONN_RETRYING) {
715 /* allow further attempts later */
716 server->state = CONN_RETRIED;
717 }
718
719 out:
720 return result;
721 }
722
723 /* smb_request_ok: We expect the server to be locked. Then we do the
724 request and check the answer completely. When smb_request_ok
725 returns 0, you can be quite sure that everything went well. When
726 the answer is <=0, the returned number is a valid unix errno. */
727
728 static int
729 smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc)
730 {
731 int result = -EIO;
732
733 s->rcls = 0;
734 s->err = 0;
735
736 /* Make sure we have a connection */
737 if (s->state != CONN_VALID) {
738 if (!smb_retry(s))
739 goto out;
740 }
741
742 if (smb_request(s) < 0) {
743 DEBUG1("smb_request failed\n");
744 goto out;
745 }
746 if (smb_valid_packet(s->packet) != 0) {
747 PARANOIA("invalid packet!\n");
748 goto out;
749 }
750
751 /*
752 * Check for server errors. The current smb_errno() routine
753 * is squashing some error codes, but I don't think this is
754 * correct: after a server error the packet won't be valid.
755 */
756 if (s->rcls != 0) {
757 result = -smb_errno(s);
758 if (!result)
759 printk(KERN_DEBUG "smb_request_ok: rcls=%d, err=%d mapped to 0\n",
760 s->rcls, s->err);
761 /*
762 * Exit now even if the error was squashed ...
763 * packet verify will fail anyway.
764 */
765 goto out;
766 }
767 result = smb_verify(s->packet, command, wct, bcc);
768
769 out:
770 return result;
771 }
772
773 /*
774 * This implements the NEWCONN ioctl. It installs the server pid,
775 * sets server->state to CONN_VALID, and wakes up the waiting process.
776 */
777 int
778 smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
779 {
780 struct file *filp;
781 int error;
782
783 VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);
784
785 smb_lock_server(server);
786
787 /*
788 * Make sure we don't already have a valid connection ...
789 */
790 error = -EINVAL;
791 if (server->state == CONN_VALID)
792 goto out;
793
794 error = -EACCES;
795 if (current->uid != server->mnt->mounted_uid &&
796 !capable(CAP_SYS_ADMIN))
797 goto out;
798
799 error = -EBADF;
800 filp = fget(opt->fd);
801 if (!filp)
802 goto out;
803 if (!smb_valid_socket(filp->f_dentry->d_inode))
804 goto out_putf;
805
806 server->sock_file = filp;
807 server->conn_pid = current->pid;
808 smb_catch_keepalive(server);
809 server->opt = *opt;
810 server->generation += 1;
811 server->state = CONN_VALID;
812 error = 0;
813
814 /* check if we have an old smbmount that uses seconds for the
815 serverzone */
816 if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60)
817 server->opt.serverzone /= 60;
818
819 /* now that we have an established connection we can detect the server
820 type and enable bug workarounds */
821 if (server->opt.protocol == SMB_PROTOCOL_NT1 &&
822 (server->opt.max_xmit < 0x1000) &&
823 !(server->opt.capabilities & SMB_CAP_NT_SMBS)) {
824 server->mnt->flags |= SMB_MOUNT_WIN95;
825 VERBOSE("smb_newconn: detected WIN95 server\n");
826 }
827
828 VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
829 server->opt.protocol, server->opt.max_xmit, server->conn_pid,
830 server->opt.capabilities);
831
832 /* Make sure we can fit a message of the negotiated size in our
833 packet buffer. */
834 if (server->opt.max_xmit > server->packet_size) {
835 int len = smb_round_length(server->opt.max_xmit);
836 char *buf = smb_vmalloc(len);
837 if (buf) {
838 if (server->packet)
839 smb_vfree(server->packet);
840 server->packet = buf;
841 server->packet_size = len;
842 } else {
843 /* else continue with the too small buffer? */
844 PARANOIA("Failed to allocate new packet buffer: "
845 "max_xmit=%d, packet_size=%d\n",
846 server->opt.max_xmit, server->packet_size);
847 server->opt.max_xmit = server->packet_size;
848 }
849 }
850
851 out:
852 smb_unlock_server(server);
853
854 #ifdef SMB_RETRY_INTR
855 wake_up_interruptible(&server->wait);
856 #else
857 wake_up(&server->wait);
858 #endif
859 return error;
860
861 out_putf:
862 fput(filp);
863 goto out;
864 }
865
866 /* smb_setup_header: We completely set up the packet. You only have to
867 insert the command-specific fields */
868
869 __u8 *
870 smb_setup_header(struct smb_sb_info * server, __u8 command, __u16 wct, __u16 bcc)
871 {
872 __u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2;
873 __u8 *p = server->packet;
874 __u8 *buf = server->packet;
875
876 if (xmit_len > server->packet_size)
877 printk(KERN_DEBUG "smb_setup_header: "
878 "Aieee, xmit len > packet! len=%d, size=%d\n",
879 xmit_len, server->packet_size);
880
881 p = smb_encode_smb_length(p, xmit_len - 4);
882
883 *p++ = 0xff;
884 *p++ = 'S';
885 *p++ = 'M';
886 *p++ = 'B';
887 *p++ = command;
888
889 memset(p, '\0', 19);
890 p += 19;
891 p += 8;
892
893 WSET(buf, smb_tid, server->opt.tid);
894 WSET(buf, smb_pid, 1);
895 WSET(buf, smb_uid, server->opt.server_uid);
896 WSET(buf, smb_mid, 1);
897
898 if (server->opt.protocol > SMB_PROTOCOL_CORE)
899 {
900 *(buf+smb_flg) = 0x8;
901 WSET(buf, smb_flg2, 0x3);
902 }
903 *p++ = wct; /* wct */
904 p += 2 * wct;
905 WSET(p, 0, bcc);
906 return p + 2;
907 }
908
909 static void
910 smb_setup_bcc(struct smb_sb_info *server, __u8 * p)
911 {
912 __u8 *packet = server->packet;
913 __u8 *pbcc = packet + SMB_HEADER_LEN + 2 * SMB_WCT(packet);
914 __u16 bcc = p - (pbcc + 2);
915
916 WSET(pbcc, 0, bcc);
917 smb_encode_smb_length(packet,
918 SMB_HEADER_LEN + 2 * SMB_WCT(packet) - 2 + bcc);
919 }
920
921 /*
922 * Called with the server locked
923 */
924 static int
925 smb_proc_seek(struct smb_sb_info *server, __u16 fileid,
926 __u16 mode, off_t offset)
927 {
928 int result;
929
930 smb_setup_header(server, SMBlseek, 4, 0);
931 WSET(server->packet, smb_vwv0, fileid);
932 WSET(server->packet, smb_vwv1, mode);
933 DSET(server->packet, smb_vwv2, offset);
934
935 result = smb_request_ok(server, SMBlseek, 2, 0);
936 if (result < 0) {
937 result = 0;
938 goto out;
939 }
940
941 result = DVAL(server->packet, smb_vwv0);
942 out:
943 return result;
944 }
945
946 /*
947 * We're called with the server locked, and we leave it that way.
948 */
949 static int
950 smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
951 {
952 struct inode *ino = dentry->d_inode;
953 int mode, read_write = 0x42, read_only = 0x40;
954 int res;
955 char *p;
956
957 /*
958 * Attempt to open r/w, unless there are no write privileges.
959 */
960 mode = read_write;
961 if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
962 mode = read_only;
963 #if 0
964 /* FIXME: why is this code not in? below we fix it so that a caller
965 wanting RO doesn't get RW. smb_revalidate_inode does some
966 optimization based on access mode. tail -f needs it to be correct.
967
968 We must open rw since we don't do the open if called a second time
969 with different 'wish'. Is that not supported by smb servers? */
970 if (!(wish & (O_WRONLY | O_RDWR)))
971 mode = read_only;
972 #endif
973
974 retry:
975 p = smb_setup_header(server, SMBopen, 2, 0);
976 WSET(server->packet, smb_vwv0, mode);
977 WSET(server->packet, smb_vwv1, aSYSTEM | aHIDDEN | aDIR);
978 *p++ = 4;
979 res = smb_encode_path(server, p, dentry, NULL);
980 if (res < 0)
981 goto out;
982 p += res;
983
984 smb_setup_bcc(server, p);
985
986 res = smb_request_ok(server, SMBopen, 7, 0);
987 if (res != 0) {
988 if (smb_retry(server))
989 goto retry;
990
991 if (mode == read_write &&
992 (res == -EACCES || res == -ETXTBSY || res == -EROFS))
993 {
994 VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
995 DENTRY_PATH(dentry), res);
996 mode = read_only;
997 goto retry;
998 }
999 goto out;
1000 }
1001 /* We should now have data in vwv[0..6]. */
1002
1003 ino->u.smbfs_i.fileid = WVAL(server->packet, smb_vwv0);
1004 ino->u.smbfs_i.attr = WVAL(server->packet, smb_vwv1);
1005 /* smb_vwv2 has mtime */
1006 /* smb_vwv4 has size */
1007 ino->u.smbfs_i.access = (WVAL(server->packet, smb_vwv6) & SMB_ACCMASK);
1008 ino->u.smbfs_i.open = server->generation;
1009
1010 out:
1011 return res;
1012 }
1013
1014 /*
1015 * Make sure the file is open, and check that the access
1016 * is compatible with the desired access.
1017 */
1018 int
1019 smb_open(struct dentry *dentry, int wish)
1020 {
1021 struct inode *inode = dentry->d_inode;
1022 int result;
1023
1024 result = -ENOENT;
1025 if (!inode) {
1026 printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
1027 DENTRY_PATH(dentry));
1028 goto out;
1029 }
1030
1031 if (!smb_is_open(inode)) {
1032 struct smb_sb_info *server = server_from_inode(inode);
1033 smb_lock_server(server);
1034 result = 0;
1035 if (!smb_is_open(inode))
1036 result = smb_proc_open(server, dentry, wish);
1037 smb_unlock_server(server);
1038 if (result) {
1039 PARANOIA("%s/%s open failed, result=%d\n",
1040 DENTRY_PATH(dentry), result);
1041 goto out;
1042 }
1043 /*
1044 * A successful open means the path is still valid ...
1045 */
1046 smb_renew_times(dentry);
1047 }
1048
1049 /*
1050 * Check whether the access is compatible with the desired mode.
1051 */
1052 result = 0;
1053 if (inode->u.smbfs_i.access != wish &&
1054 inode->u.smbfs_i.access != SMB_O_RDWR)
1055 {
1056 PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
1057 DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
1058 result = -EACCES;
1059 }
1060 out:
1061 return result;
1062 }
1063
1064 /* We're called with the server locked */
1065
1066 static int
1067 smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime)
1068 {
1069 smb_setup_header(server, SMBclose, 3, 0);
1070 WSET(server->packet, smb_vwv0, fileid);
1071 DSET(server->packet, smb_vwv1, utc2local(server, mtime));
1072 return smb_request_ok(server, SMBclose, 0, 0);
1073 }
1074
1075 /*
1076 * Called with the server locked.
1077 *
1078 * Win NT 4.0 has an apparent bug in that it fails to update the
1079 * modify time when writing to a file. As a workaround, we update
1080 * both modify and access time locally, and post the times to the
1081 * server when closing the file.
1082 */
1083 static int
1084 smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino)
1085 {
1086 int result = 0;
1087 if (smb_is_open(ino))
1088 {
1089 /*
1090 * We clear the open flag in advance, in case another
1091 * process observes the value while we block below.
1092 */
1093 ino->u.smbfs_i.open = 0;
1094
1095 /*
1096 * Kludge alert: SMB timestamps are accurate only to
1097 * two seconds ... round the times to avoid needless
1098 * cache invalidations!
1099 */
1100 if (ino->i_mtime & 1)
1101 ino->i_mtime--;
1102 if (ino->i_atime & 1)
1103 ino->i_atime--;
1104 /*
1105 * If the file is open with write permissions,
1106 * update the time stamps to sync mtime and atime.
1107 */
1108 if ((server->opt.protocol >= SMB_PROTOCOL_LANMAN2) &&
1109 !(ino->u.smbfs_i.access == SMB_O_RDONLY))
1110 {
1111 struct smb_fattr fattr;
1112 smb_get_inode_attr(ino, &fattr);
1113 smb_proc_setattr_ext(server, ino, &fattr);
1114 }
1115
1116 result = smb_proc_close(server, ino->u.smbfs_i.fileid,
1117 ino->i_mtime);
1118 /*
1119 * Force a revalidation after closing ... some servers
1120 * don't post the size until the file has been closed.
1121 */
1122 if (server->opt.protocol < SMB_PROTOCOL_NT1)
1123 ino->u.smbfs_i.oldmtime = 0;
1124 ino->u.smbfs_i.closed = jiffies;
1125 }
1126 return result;
1127 }
1128
1129 int
1130 smb_close(struct inode *ino)
1131 {
1132 int result = 0;
1133
1134 if (smb_is_open(ino)) {
1135 struct smb_sb_info *server = server_from_inode(ino);
1136 smb_lock_server(server);
1137 result = smb_proc_close_inode(server, ino);
1138 smb_unlock_server(server);
1139 }
1140 return result;
1141 }
1142
1143 /*
1144 * This is used to close a file following a failed instantiate.
1145 * Since we don't have an inode, we can't use any of the above.
1146 */
1147 int
1148 smb_close_fileid(struct dentry *dentry, __u16 fileid)
1149 {
1150 struct smb_sb_info *server = server_from_dentry(dentry);
1151 int result;
1152
1153 smb_lock_server(server);
1154 result = smb_proc_close(server, fileid, CURRENT_TIME);
1155 smb_unlock_server(server);
1156 return result;
1157 }
1158
1159 /* In smb_proc_read and smb_proc_write we do not retry, because the
1160 file-id would not be valid after a reconnection. */
1161
1162 int
1163 smb_proc_read(struct inode *inode, off_t offset, int count, char *data)
1164 {
1165 struct smb_sb_info *server = server_from_inode(inode);
1166 __u16 returned_count, data_len;
1167 unsigned char *buf;
1168 int result;
1169
1170 smb_lock_server(server);
1171 smb_setup_header(server, SMBread, 5, 0);
1172 buf = server->packet;
1173 WSET(buf, smb_vwv0, inode->u.smbfs_i.fileid);
1174 WSET(buf, smb_vwv1, count);
1175 DSET(buf, smb_vwv2, offset);
1176 WSET(buf, smb_vwv4, 0);
1177
1178 result = smb_request_ok(server, SMBread, 5, -1);
1179 if (result < 0)
1180 goto out;
1181 returned_count = WVAL(server->packet, smb_vwv0);
1182
1183 buf = SMB_BUF(server->packet);
1184 data_len = WVAL(buf, 1);
1185
1186 /* we can NOT simply trust the data_len given by the server ... */
1187 if (data_len > server->packet_size - (buf+3 - server->packet)) {
1188 printk(KERN_ERR "smb_proc_read: invalid data length!! "
1189 "%d > %d - (%p - %p)\n",
1190 data_len, server->packet_size, buf+3, server->packet);
1191 result = -EIO;
1192 goto out;
1193 }
1194
1195 memcpy(data, buf+3, data_len);
1196
1197 if (returned_count != data_len) {
1198 printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
1199 printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
1200 returned_count, data_len);
1201 }
1202 result = data_len;
1203
1204 out:
1205 VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
1206 inode->i_ino, inode->u.smbfs_i.fileid, count, result);
1207 smb_unlock_server(server);
1208 return result;
1209 }
1210
1211 int
1212 smb_proc_write(struct inode *inode, off_t offset, int count, const char *data)
1213 {
1214 struct smb_sb_info *server = server_from_inode(inode);
1215 int result;
1216 __u8 *p;
1217 __u16 fileid = inode->u.smbfs_i.fileid;
1218
1219 VERBOSE("ino=%ld, fileid=%d, count=%d@%ld, packet_size=%d\n",
1220 inode->i_ino, inode->u.smbfs_i.fileid, count, offset,
1221 server->packet_size);
1222
1223 smb_lock_server(server);
1224 p = smb_setup_header(server, SMBwrite, 5, count + 3);
1225 WSET(server->packet, smb_vwv0, fileid);
1226 WSET(server->packet, smb_vwv1, count);
1227 DSET(server->packet, smb_vwv2, offset);
1228 WSET(server->packet, smb_vwv4, 0);
1229
1230 *p++ = 1;
1231 WSET(p, 0, count);
1232 memcpy(p+2, data, count);
1233
1234 result = smb_request_ok(server, SMBwrite, 1, 0);
1235 if (result >= 0)
1236 result = WVAL(server->packet, smb_vwv0);
1237
1238 smb_unlock_server(server);
1239 return result;
1240 }
1241
1242 int
1243 smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid)
1244 {
1245 struct smb_sb_info *server = server_from_dentry(dentry);
1246 char *p;
1247 int result;
1248
1249 smb_lock_server(server);
1250
1251 retry:
1252 p = smb_setup_header(server, SMBcreate, 3, 0);
1253 WSET(server->packet, smb_vwv0, attr);
1254 DSET(server->packet, smb_vwv1, utc2local(server, ctime));
1255 *p++ = 4;
1256 result = smb_encode_path(server, p, dentry, NULL);
1257 if (result < 0)
1258 goto out;
1259 p += result;
1260 smb_setup_bcc(server, p);
1261
1262 result = smb_request_ok(server, SMBcreate, 1, 0);
1263 if (result < 0) {
1264 if (smb_retry(server))
1265 goto retry;
1266 goto out;
1267 }
1268 *fileid = WVAL(server->packet, smb_vwv0);
1269 result = 0;
1270
1271 out:
1272 smb_unlock_server(server);
1273 return result;
1274 }
1275
1276 int
1277 smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry)
1278 {
1279 struct smb_sb_info *server = server_from_dentry(old_dentry);
1280 char *p;
1281 int result;
1282
1283 smb_lock_server(server);
1284
1285 retry:
1286 p = smb_setup_header(server, SMBmv, 1, 0);
1287 WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
1288
1289 *p++ = 4;
1290 result = smb_encode_path(server, p, old_dentry, NULL);
1291 if (result < 0)
1292 goto out;
1293 p += result;
1294
1295 *p++ = 4;
1296 result = smb_encode_path(server, p, new_dentry, NULL);
1297 if (result < 0)
1298 goto out;
1299 p += result;
1300
1301 smb_setup_bcc(server, p);
1302
1303 if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0) {
1304 if (smb_retry(server))
1305 goto retry;
1306 goto out;
1307 }
1308 result = 0;
1309 out:
1310 smb_unlock_server(server);
1311 return result;
1312 }
1313
1314 /*
1315 * Code common to mkdir and rmdir.
1316 */
1317 static int
1318 smb_proc_generic_command(struct dentry *dentry, __u8 command)
1319 {
1320 struct smb_sb_info *server = server_from_dentry(dentry);
1321 char *p;
1322 int result;
1323
1324 smb_lock_server(server);
1325
1326 retry:
1327 p = smb_setup_header(server, command, 0, 0);
1328 *p++ = 4;
1329 result = smb_encode_path(server, p, dentry, NULL);
1330 if (result < 0)
1331 goto out;
1332 p += result;
1333 smb_setup_bcc(server, p);
1334
1335 result = smb_request_ok(server, command, 0, 0);
1336 if (result < 0) {
1337 if (smb_retry(server))
1338 goto retry;
1339 goto out;
1340 }
1341 result = 0;
1342 out:
1343 smb_unlock_server(server);
1344 return result;
1345 }
1346
1347 int
1348 smb_proc_mkdir(struct dentry *dentry)
1349 {
1350 return smb_proc_generic_command(dentry, SMBmkdir);
1351 }
1352
1353 int
1354 smb_proc_rmdir(struct dentry *dentry)
1355 {
1356 return smb_proc_generic_command(dentry, SMBrmdir);
1357 }
1358
1359 #if SMBFS_POSIX_UNLINK
1360 /*
1361 * Removes readonly attribute from a file. Used by unlink to give posix
1362 * semantics.
1363 * Note: called with the server locked.
1364 */
1365 static int
1366 smb_set_rw(struct dentry *dentry,struct smb_sb_info *server)
1367 {
1368 int result;
1369 struct smb_fattr fattr;
1370
1371 /* first get current attribute */
1372 result = smb_proc_do_getattr(server, dentry, &fattr);
1373 if (result < 0)
1374 return result;
1375
1376 /* if RONLY attribute is set, remove it */
1377 if (fattr.attr & aRONLY) { /* read only attribute is set */
1378 fattr.attr &= ~aRONLY;
1379 result = smb_proc_setattr_core(server, dentry, fattr.attr);
1380 }
1381 return result;
1382 }
1383 #endif
1384
1385 int
1386 smb_proc_unlink(struct dentry *dentry)
1387 {
1388 struct smb_sb_info *server = server_from_dentry(dentry);
1389 int flag = 0;
1390 char *p;
1391 int result;
1392
1393 smb_lock_server(server);
1394
1395 retry:
1396 p = smb_setup_header(server, SMBunlink, 1, 0);
1397 WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
1398 *p++ = 4;
1399 result = smb_encode_path(server, p, dentry, NULL);
1400 if (result < 0)
1401 goto out;
1402 p += result;
1403 smb_setup_bcc(server, p);
1404
1405 if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0) {
1406 #if SMBFS_POSIX_UNLINK
1407 if (result == -EACCES && !flag) {
1408 /* Posix semantics is for the read-only state
1409 of a file to be ignored in unlink(). In the
1410 SMB world a unlink() is refused on a
1411 read-only file. To make things easier for
1412 unix users we try to override the files
1413 permission if the unlink fails with the
1414 right error.
1415 This introduces a race condition that could
1416 lead to a file being written by someone who
1417 shouldn't have access, but as far as I can
1418 tell that is unavoidable */
1419
1420 /* remove RONLY attribute and try again */
1421 result = smb_set_rw(dentry,server);
1422 if (result == 0) {
1423 flag = 1;
1424 goto retry;
1425 }
1426 }
1427 #endif
1428 if (smb_retry(server))
1429 goto retry;
1430 goto out;
1431 }
1432 result = 0;
1433 out:
1434 smb_unlock_server(server);
1435 return result;
1436 }
1437
1438 /*
1439 * Called with the server locked
1440 */
1441 int
1442 smb_proc_flush(struct smb_sb_info *server, __u16 fileid)
1443 {
1444 smb_setup_header(server, SMBflush, 1, 0);
1445 WSET(server->packet, smb_vwv0, fileid);
1446 return smb_request_ok(server, SMBflush, 0, 0);
1447 }
1448
1449 int
1450 smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length)
1451 {
1452 char *p;
1453 int result;
1454
1455 smb_lock_server(server);
1456
1457 retry:
1458 p = smb_setup_header(server, SMBwrite, 5, 3);
1459 WSET(server->packet, smb_vwv0, fid);
1460 WSET(server->packet, smb_vwv1, 0);
1461 DSET(server->packet, smb_vwv2, length);
1462 WSET(server->packet, smb_vwv4, 0);
1463 *p++ = 1;
1464 WSET(p, 0, 0);
1465
1466 if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0) {
1467 if (smb_retry(server))
1468 goto retry;
1469 goto out;
1470 }
1471
1472 /*
1473 * win9x doesn't appear to update the size immediately.
1474 * It will return the old file size after the truncate,
1475 * confusing smbfs.
1476 * NT and Samba return the new value immediately.
1477 */
1478 if (server->mnt->flags & SMB_MOUNT_WIN95)
1479 smb_proc_flush(server, fid);
1480 out:
1481 smb_unlock_server(server);
1482 return result;
1483 }
1484
1485 static void
1486 smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1487 {
1488 memset(fattr, 0, sizeof(*fattr));
1489
1490 fattr->f_nlink = 1;
1491 fattr->f_uid = server->mnt->uid;
1492 fattr->f_gid = server->mnt->gid;
1493 fattr->f_blksize = 512;
1494 }
1495
1496 static void
1497 smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1498 {
1499 fattr->f_mode = server->mnt->file_mode;
1500 if (fattr->attr & aDIR)
1501 {
1502 fattr->f_mode = server->mnt->dir_mode;
1503 fattr->f_size = 512;
1504 }
1505 /* Check the read-only flag */
1506 if (fattr->attr & aRONLY)
1507 fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
1508
1509 fattr->f_blocks = 0;
1510 if ((fattr->f_blksize != 0) && (fattr->f_size != 0))
1511 {
1512 fattr->f_blocks =
1513 (fattr->f_size - 1) / fattr->f_blksize + 1;
1514 }
1515 return;
1516 }
1517
1518 void
1519 smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1520 {
1521 smb_init_dirent(server, fattr);
1522 fattr->attr = aDIR;
1523 fattr->f_ino = 2; /* traditional root inode number */
1524 fattr->f_mtime = CURRENT_TIME;
1525 smb_finish_dirent(server, fattr);
1526 }
1527
1528 /*
1529 * Decode a dirent for old protocols
1530 *
1531 * qname is filled with the decoded, and possibly translated, name.
1532 * fattr receives decoded attributes
1533 *
1534 * Bugs Noted:
1535 * (1) Pathworks servers may pad the name with extra spaces.
1536 */
1537 static char *
1538 smb_decode_short_dirent(struct smb_sb_info *server, char *p,
1539 struct qstr *qname, struct smb_fattr *fattr)
1540 {
1541 int len;
1542
1543 /*
1544 * SMB doesn't have a concept of inode numbers ...
1545 */
1546 smb_init_dirent(server, fattr);
1547 fattr->f_ino = 0; /* FIXME: do we need this? */
1548
1549 p += SMB_STATUS_SIZE; /* reserved (search_status) */
1550 fattr->attr = *p;
1551 fattr->f_mtime = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1));
1552 fattr->f_size = DVAL(p, 5);
1553 fattr->f_ctime = fattr->f_mtime;
1554 fattr->f_atime = fattr->f_mtime;
1555 qname->name = p + 9;
1556 len = strnlen(qname->name, 12);
1557
1558 /*
1559 * Trim trailing blanks for Pathworks servers
1560 */
1561 while (len > 2 && qname->name[len-1] == ' ')
1562 len--;
1563 qname->len = len;
1564
1565 smb_finish_dirent(server, fattr);
1566
1567 #if 0
1568 /* FIXME: These only work for ascii chars, and recent smbmount doesn't
1569 allow the flag to be set anyway. It kills const. Remove? */
1570 switch (server->opt.case_handling) {
1571 case SMB_CASE_UPPER:
1572 str_upper(entry->name, len);
1573 break;
1574 case SMB_CASE_LOWER:
1575 str_lower(entry->name, len);
1576 break;
1577 default:
1578 break;
1579 }
1580 #endif
1581
1582 qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN,
1583 qname->name, len,
1584 server->remote_nls, server->local_nls);
1585 qname->name = server->name_buf;
1586
1587 DEBUG1("len=%d, name=%.*s\n", qname->len, qname->len, qname->name);
1588 return p + 22;
1589 }
1590
1591 /*
1592 * This routine is used to read in directory entries from the network.
1593 * Note that it is for short directory name seeks, i.e.: protocol <
1594 * SMB_PROTOCOL_LANMAN2
1595 */
1596 static int
1597 smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
1598 struct smb_cache_control *ctl)
1599 {
1600 struct dentry *dir = filp->f_dentry;
1601 struct smb_sb_info *server = server_from_dentry(dir);
1602 struct qstr qname;
1603 struct smb_fattr fattr;
1604
1605 unsigned char *p;
1606 int result;
1607 int i, first, entries_seen, entries;
1608 int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE;
1609 __u16 bcc;
1610 __u16 count;
1611 char status[SMB_STATUS_SIZE];
1612 static struct qstr mask = { "*.*", 3, 0 };
1613 unsigned char *last_status;
1614
1615 VERBOSE("%s/%s\n", DENTRY_PATH(dir));
1616
1617 smb_lock_server(server);
1618
1619 first = 1;
1620 entries = 0;
1621 entries_seen = 2; /* implicit . and .. */
1622
1623 while (1) {
1624 p = smb_setup_header(server, SMBsearch, 2, 0);
1625 WSET(server->packet, smb_vwv0, entries_asked);
1626 WSET(server->packet, smb_vwv1, aDIR);
1627 *p++ = 4;
1628 if (first == 1) {
1629 result = smb_encode_path(server, p, dir, &mask);
1630 if (result < 0)
1631 goto unlock_return;
1632 p += result;
1633 *p++ = 5;
1634 WSET(p, 0, 0);
1635 p += 2;
1636 first = 0;
1637 } else {
1638 *p++ = 0;
1639 *p++ = 5;
1640 WSET(p, 0, SMB_STATUS_SIZE);
1641 p += 2;
1642 memcpy(p, status, SMB_STATUS_SIZE);
1643 p += SMB_STATUS_SIZE;
1644 }
1645
1646 smb_setup_bcc(server, p);
1647
1648 result = smb_request_ok(server, SMBsearch, 1, -1);
1649 if (result < 0) {
1650 if ((server->rcls == ERRDOS) &&
1651 (server->err == ERRnofiles))
1652 break;
1653 if (smb_retry(server)) {
1654 ctl->idx = -1; /* retry */
1655 result = 0;
1656 }
1657 goto unlock_return;
1658 }
1659 p = SMB_VWV(server->packet);
1660 count = WVAL(p, 0);
1661 if (count <= 0)
1662 break;
1663
1664 result = -EIO;
1665 bcc = WVAL(p, 2);
1666 if (bcc != count * SMB_DIRINFO_SIZE + 3)
1667 goto unlock_return;
1668 p += 7;
1669
1670
1671 /* Make sure the response fits in the buffer. Fixed sized
1672 entries means we don't have to check in the decode loop. */
1673
1674 last_status = SMB_BUF(server->packet) + 3 + (count - 1) *
1675 SMB_DIRINFO_SIZE;
1676
1677 if (last_status + SMB_DIRINFO_SIZE >=
1678 server->packet + server->packet_size) {
1679 printk(KERN_ERR "smb_proc_readdir_short: "
1680 "last dir entry outside buffer! "
1681 "%d@%p %d@%p\n", SMB_DIRINFO_SIZE, last_status,
1682 server->packet_size, server->packet);
1683 goto unlock_return;
1684 }
1685
1686 /* Read the last entry into the status field. */
1687 memcpy(status, last_status, SMB_STATUS_SIZE);
1688
1689
1690 /* Now we are ready to parse smb directory entries. */
1691
1692 for (i = 0; i < count; i++) {
1693 p = smb_decode_short_dirent(server, p,
1694 &qname, &fattr);
1695
1696 if (entries_seen == 2 && qname.name[0] == '.') {
1697 if (qname.len == 1)
1698 continue;
1699 if (qname.name[1] == '.' && qname.len == 2)
1700 continue;
1701 }
1702 if (!smb_fill_cache(filp, dirent, filldir, ctl,
1703 &qname, &fattr))
1704 ; /* stop reading? */
1705 entries_seen++;
1706 }
1707 }
1708 result = entries;
1709
1710 unlock_return:
1711 smb_unlock_server(server);
1712 return result;
1713 }
1714
1715 /*
1716 * Interpret a long filename structure using the specified info level:
1717 * level 1 for anything below NT1 protocol
1718 * level 260 for NT1 protocol
1719 *
1720 * qname is filled with the decoded, and possibly translated, name
1721 * fattr receives decoded attributes.
1722 *
1723 * Bugs Noted:
1724 * (1) Win NT 4.0 appends a null byte to names and counts it in the length!
1725 */
1726 static char *
1727 smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level,
1728 struct qstr *qname, struct smb_fattr *fattr)
1729 {
1730 char *result;
1731 unsigned int len = 0;
1732 __u16 date, time;
1733
1734 /*
1735 * SMB doesn't have a concept of inode numbers ...
1736 */
1737 smb_init_dirent(server, fattr);
1738 fattr->f_ino = 0; /* FIXME: do we need this? */
1739
1740 switch (level) {
1741 case 1:
1742 len = *((unsigned char *) p + 22);
1743 qname->name = p + 23;
1744 result = p + 24 + len;
1745
1746 date = WVAL(p, 0);
1747 time = WVAL(p, 2);
1748 fattr->f_ctime = date_dos2unix(server, date, time);
1749
1750 date = WVAL(p, 4);
1751 time = WVAL(p, 6);
1752 fattr->f_atime = date_dos2unix(server, date, time);
1753
1754 date = WVAL(p, 8);
1755 time = WVAL(p, 10);
1756 fattr->f_mtime = date_dos2unix(server, date, time);
1757 fattr->f_size = DVAL(p, 12);
1758 /* ULONG allocation size */
1759 fattr->attr = WVAL(p, 20);
1760
1761 VERBOSE("info 1 at %p, len=%d, name=%.*s\n",
1762 p, len, len, qname->name);
1763 break;
1764 case 260:
1765 result = p + WVAL(p, 0);
1766 len = DVAL(p, 60);
1767 if (len > 255) len = 255;
1768 /* NT4 null terminates */
1769 qname->name = p + 94;
1770 if (len && qname->name[len-1] == '\0')
1771 len--;
1772
1773 fattr->f_ctime = smb_ntutc2unixutc(server, LVAL(p, 8));
1774 fattr->f_atime = smb_ntutc2unixutc(server, LVAL(p, 16));
1775 fattr->f_mtime = smb_ntutc2unixutc(server, LVAL(p, 24));
1776 /* change time (32) */
1777 fattr->f_size = DVAL(p, 40);
1778 /* alloc size (48) */
1779 fattr->attr = DVAL(p, 56);
1780
1781 VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
1782 p, len, len, qname->name);
1783 break;
1784 default:
1785 PARANOIA("Unknown info level %d\n", level);
1786 result = p + WVAL(p, 0);
1787 goto out;
1788 }
1789
1790 smb_finish_dirent(server, fattr);
1791
1792 #if 0
1793 /* FIXME: These only work for ascii chars, and recent smbmount doesn't
1794 allow the flag to be set anyway. Remove? */
1795 switch (server->opt.case_handling) {
1796 case SMB_CASE_UPPER:
1797 str_upper(qname->name, len);
1798 break;
1799 case SMB_CASE_LOWER:
1800 str_lower(qname->name, len);
1801 break;
1802 default:
1803 break;
1804 }
1805 #endif
1806
1807 qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN,
1808 qname->name, len,
1809 server->remote_nls, server->local_nls);
1810 qname->name = server->name_buf;
1811
1812 out:
1813 return result;
1814 }
1815
1816 /* findfirst/findnext flags */
1817 #define SMB_CLOSE_AFTER_FIRST (1<<0)
1818 #define SMB_CLOSE_IF_END (1<<1)
1819 #define SMB_REQUIRE_RESUME_KEY (1<<2)
1820 #define SMB_CONTINUE_BIT (1<<3)
1821
1822 /*
1823 * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in
1824 * source/libsmb/clilist.c. When looking for smb bugs in the readdir code,
1825 * go there for advise.
1826 *
1827 * Bugs Noted:
1828 * (1) When using Info Level 1 Win NT 4.0 truncates directory listings
1829 * for certain patterns of names and/or lengths. The breakage pattern
1830 * is completely reproducible and can be toggled by the creation of a
1831 * single file. (E.g. echo hi >foo breaks, rm -f foo works.)
1832 */
1833 static int
1834 smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
1835 struct smb_cache_control *ctl)
1836 {
1837 struct dentry *dir = filp->f_dentry;
1838 struct smb_sb_info *server = server_from_dentry(dir);
1839 struct qstr qname;
1840 struct smb_fattr fattr;
1841
1842 unsigned char *p, *lastname;
1843 char *mask, *param = server->temp_buf;
1844 __u16 command;
1845 int first, entries_seen;
1846
1847 /* Both NT and OS/2 accept info level 1 (but see note below). */
1848 int info_level = 260;
1849 const int max_matches = 512;
1850
1851 unsigned char *resp_data = NULL;
1852 unsigned char *resp_param = NULL;
1853 int resp_data_len = 0;
1854 int resp_param_len = 0;
1855 int ff_searchcount = 0;
1856 int ff_eos = 0;
1857 int ff_lastname = 0;
1858 int ff_dir_handle = 0;
1859 int loop_count = 0;
1860 int mask_len, i, result;
1861 static struct qstr star = { "*", 1, 0 };
1862
1863 /*
1864 * use info level 1 for older servers that don't do 260
1865 */
1866 if (server->opt.protocol < SMB_PROTOCOL_NT1)
1867 info_level = 1;
1868
1869 smb_lock_server(server);
1870
1871 /*
1872 * Encode the initial path
1873 */
1874 mask = param + 12;
1875
1876 mask_len = smb_encode_path(server, mask, dir, &star);
1877 if (mask_len < 0) {
1878 result = mask_len;
1879 goto unlock_return;
1880 }
1881 mask_len--; /* mask_len is strlen, not #bytes */
1882 first = 1;
1883 VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);
1884
1885 result = 0;
1886 entries_seen = 2;
1887 ff_eos = 0;
1888
1889 while (ff_eos == 0) {
1890 loop_count += 1;
1891 if (loop_count > 10) {
1892 printk(KERN_WARNING "smb_proc_readdir_long: "
1893 "Looping in FIND_NEXT??\n");
1894 result = -EIO;
1895 break;
1896 }
1897
1898 if (first != 0) {
1899 command = TRANSACT2_FINDFIRST;
1900 WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
1901 WSET(param, 2, max_matches); /* max count */
1902 WSET(param, 4, SMB_CLOSE_IF_END);
1903 WSET(param, 6, info_level);
1904 DSET(param, 8, 0);
1905 } else {
1906 command = TRANSACT2_FINDNEXT;
1907
1908 VERBOSE("handle=0x%X, lastname=%d, mask=%s\n",
1909 ff_dir_handle, ff_lastname, mask);
1910
1911 WSET(param, 0, ff_dir_handle); /* search handle */
1912 WSET(param, 2, max_matches); /* max count */
1913 WSET(param, 4, info_level);
1914 DSET(param, 6, 0);
1915 WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
1916 }
1917
1918 result = smb_trans2_request(server, command,
1919 0, NULL, 12 + mask_len + 1, param,
1920 &resp_data_len, &resp_data,
1921 &resp_param_len, &resp_param);
1922
1923 if (result < 0) {
1924 if (smb_retry(server)) {
1925 PARANOIA("error=%d, retrying\n", result);
1926 ctl->idx = -1; /* retry */
1927 result = 0;
1928 goto unlock_return;
1929 }
1930 PARANOIA("error=%d, breaking\n", result);
1931 break;
1932 }
1933
1934 if (server->rcls == ERRSRV && server->err == ERRerror) {
1935 /* a damn Win95 bug - sometimes it clags if you
1936 ask it too fast */
1937 current->state = TASK_INTERRUPTIBLE;
1938 schedule_timeout(HZ/5);
1939 continue;
1940 }
1941
1942 if (server->rcls != 0) {
1943 result = -smb_errno(server);
1944 PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",
1945 mask, result, server->rcls, server->err);
1946 break;
1947 }
1948
1949 /* parse out some important return info */
1950 if (first != 0) {
1951 ff_dir_handle = WVAL(resp_param, 0);
1952 ff_searchcount = WVAL(resp_param, 2);
1953 ff_eos = WVAL(resp_param, 4);
1954 ff_lastname = WVAL(resp_param, 8);
1955 } else {
1956 ff_searchcount = WVAL(resp_param, 0);
1957 ff_eos = WVAL(resp_param, 2);
1958 ff_lastname = WVAL(resp_param, 6);
1959 }
1960
1961 if (ff_searchcount == 0)
1962 break;
1963
1964 /*
1965 * We might need the lastname for continuations.
1966 *
1967 * Note that some servers (win95?) point to the filename and
1968 * others (NT4, Samba using NT1) to the dir entry. We assume
1969 * here that those who do not point to a filename do not need
1970 * this info to continue the listing.
1971 *
1972 * OS/2 needs this and talks infolevel 1
1973 * NetApps want lastname with infolevel 260
1974 *
1975 * Both are happy if we return the data they point to. So we do.
1976 */
1977 mask_len = 0;
1978 if (ff_lastname > 0 && ff_lastname < resp_data_len) {
1979 lastname = resp_data + ff_lastname;
1980
1981 switch (info_level) {
1982 case 260:
1983 mask_len = resp_data_len - ff_lastname;
1984 break;
1985 case 1:
1986 /* lastname points to a length byte */
1987 mask_len = *lastname++;
1988 if (ff_lastname + 1 + mask_len > resp_data_len)
1989 mask_len = resp_data_len - ff_lastname - 1;
1990 break;
1991 }
1992
1993 /*
1994 * Update the mask string for the next message.
1995 */
1996 if (mask_len < 0)
1997 mask_len = 0;
1998 if (mask_len > 255)
1999 mask_len = 255;
2000 if (mask_len)
2001 strncpy(mask, lastname, mask_len);
2002 }
2003 mask_len = strnlen(mask, mask_len);
2004 VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n",
2005 mask_len, ff_lastname, resp_data_len, mask_len, mask);
2006
2007 /* Now we are ready to parse smb directory entries. */
2008
2009 /* point to the data bytes */
2010 p = resp_data;
2011 for (i = 0; i < ff_searchcount; i++) {
2012 /* make sure we stay within the buffer */
2013 if (p >= resp_data + resp_data_len) {
2014 printk(KERN_ERR "smb_proc_readdir_long: "
2015 "dirent pointer outside buffer! "
2016 "%p %d@%p %d@%p\n",
2017 p, resp_data_len, resp_data,
2018 server->packet_size, server->packet);
2019 result = -EIO; /* always a comm. error? */
2020 goto unlock_return;
2021 }
2022
2023 p = smb_decode_long_dirent(server, p, info_level,
2024 &qname, &fattr);
2025
2026 /* ignore . and .. from the server */
2027 if (entries_seen == 2 && qname.name[0] == '.') {
2028 if (qname.len == 1)
2029 continue;
2030 if (qname.name[1] == '.' && qname.len == 2)
2031 continue;
2032 }
2033
2034 if (!smb_fill_cache(filp, dirent, filldir, ctl,
2035 &qname, &fattr))
2036 ; /* stop reading? */
2037 entries_seen++;
2038 }
2039
2040 VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos);
2041
2042 first = 0;
2043 loop_count = 0;
2044 }
2045
2046 unlock_return:
2047 smb_unlock_server(server);
2048 return result;
2049 }
2050
2051 int
2052 smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir,
2053 struct smb_cache_control *ctl)
2054 {
2055 struct smb_sb_info *server = server_from_dentry(filp->f_dentry);
2056
2057 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
2058 return smb_proc_readdir_long(filp, dirent, filldir, ctl);
2059 else
2060 return smb_proc_readdir_short(filp, dirent, filldir, ctl);
2061 }
2062
2063 /*
2064 * This version uses the trans2 TRANSACT2_FINDFIRST message
2065 * to get the attribute data.
2066 * Note: called with the server locked.
2067 *
2068 * Bugs Noted:
2069 */
2070 static int
2071 smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
2072 struct smb_fattr *fattr)
2073 {
2074 char *param = server->temp_buf, *mask = param + 12;
2075 __u16 date, time;
2076 unsigned char *resp_data = NULL;
2077 unsigned char *resp_param = NULL;
2078 int resp_data_len = 0;
2079 int resp_param_len = 0;
2080 int mask_len, result;
2081
2082 retry:
2083 mask_len = smb_encode_path(server, mask, dentry, NULL);
2084 if (mask_len < 0) {
2085 result = mask_len;
2086 goto out;
2087 }
2088 VERBOSE("name=%s, len=%d\n", mask, mask_len);
2089 WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
2090 WSET(param, 2, 1); /* max count */
2091 WSET(param, 4, 1); /* close after this call */
2092 WSET(param, 6, 1); /* info_level */
2093 DSET(param, 8, 0);
2094
2095 result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
2096 0, NULL, 12 + mask_len, param,
2097 &resp_data_len, &resp_data,
2098 &resp_param_len, &resp_param);
2099 if (result < 0)
2100 {
2101 if (smb_retry(server))
2102 goto retry;
2103 goto out;
2104 }
2105 if (server->rcls != 0)
2106 {
2107 result = -smb_errno(server);
2108 #ifdef SMBFS_PARANOIA
2109 if (result != -ENOENT)
2110 PARANOIA("error for %s, rcls=%d, err=%d\n",
2111 mask, server->rcls, server->err);
2112 #endif
2113 goto out;
2114 }
2115 /* Make sure we got enough data ... */
2116 result = -EINVAL;
2117 if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)
2118 {
2119 PARANOIA("bad result for %s, len=%d, count=%d\n",
2120 mask, resp_data_len, WVAL(resp_param, 2));
2121 goto out;
2122 }
2123
2124 /*
2125 * Decode the response into the fattr ...
2126 */
2127 date = WVAL(resp_data, 0);
2128 time = WVAL(resp_data, 2);
2129 fattr->f_ctime = date_dos2unix(server, date, time);
2130
2131 date = WVAL(resp_data, 4);
2132 time = WVAL(resp_data, 6);
2133 fattr->f_atime = date_dos2unix(server, date, time);
2134
2135 date = WVAL(resp_data, 8);
2136 time = WVAL(resp_data, 10);
2137 fattr->f_mtime = date_dos2unix(server, date, time);
2138 VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n",
2139 mask, date, time, fattr->f_mtime);
2140 fattr->f_size = DVAL(resp_data, 12);
2141 /* ULONG allocation size */
2142 fattr->attr = WVAL(resp_data, 20);
2143 result = 0;
2144
2145 out:
2146 return result;
2147 }
2148
2149 /*
2150 * Note: called with the server locked.
2151 */
2152 static int
2153 smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
2154 struct smb_fattr *fattr)
2155 {
2156 int result;
2157 char *p;
2158
2159 retry:
2160 p = smb_setup_header(server, SMBgetatr, 0, 0);
2161 *p++ = 4;
2162 result = smb_encode_path(server, p, dir, NULL);
2163 if (result < 0)
2164 goto out;
2165 p += result;
2166 smb_setup_bcc(server, p);
2167
2168 if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)
2169 {
2170 if (smb_retry(server))
2171 goto retry;
2172 goto out;
2173 }
2174 fattr->attr = WVAL(server->packet, smb_vwv0);
2175 fattr->f_mtime = local2utc(server, DVAL(server->packet, smb_vwv1));
2176 fattr->f_size = DVAL(server->packet, smb_vwv3);
2177 fattr->f_ctime = fattr->f_mtime;
2178 fattr->f_atime = fattr->f_mtime;
2179 #ifdef SMBFS_DEBUG_TIMESTAMP
2180 printk("getattr_core: %s/%s, mtime=%ld\n",
2181 DENTRY_PATH(dir), fattr->f_mtime);
2182 #endif
2183 result = 0;
2184
2185 out:
2186 return result;
2187 }
2188
2189 /*
2190 * Note: called with the server locked.
2191 *
2192 * Bugs Noted:
2193 * (1) Win 95 swaps the date and time fields in the standard info level.
2194 */
2195 static int
2196 smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
2197 struct smb_fattr *attr)
2198 {
2199 char *p, *param = server->temp_buf;
2200 __u16 date, time;
2201 int off_date = 0, off_time = 2;
2202 unsigned char *resp_data = NULL;
2203 unsigned char *resp_param = NULL;
2204 int resp_data_len = 0;
2205 int resp_param_len = 0;
2206 int result;
2207
2208 retry:
2209 WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */
2210 DSET(param, 2, 0);
2211 result = smb_encode_path(server, param + 6, dir, NULL);
2212 if (result < 0)
2213 goto out;
2214 p = param + 6 + result;
2215
2216 result = smb_trans2_request(server, TRANSACT2_QPATHINFO,
2217 0, NULL, p - param, param,
2218 &resp_data_len, &resp_data,
2219 &resp_param_len, &resp_param);
2220 if (result < 0)
2221 {
2222 if (smb_retry(server))
2223 goto retry;
2224 goto out;
2225 }
2226 if (server->rcls != 0)
2227 {
2228 VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
2229 ¶m[6], result, server->rcls, server->err);
2230 result = -smb_errno(server);
2231 goto out;
2232 }
2233 result = -ENOENT;
2234 if (resp_data_len < 22)
2235 {
2236 PARANOIA("not enough data for %s, len=%d\n",
2237 ¶m[6], resp_data_len);
2238 goto out;
2239 }
2240
2241 /*
2242 * Kludge alert: Win 95 swaps the date and time field,
2243 * contrary to the CIFS docs and Win NT practice.
2244 */
2245 if (server->mnt->flags & SMB_MOUNT_WIN95) {
2246 off_date = 2;
2247 off_time = 0;
2248 }
2249 date = WVAL(resp_data, off_date);
2250 time = WVAL(resp_data, off_time);
2251 attr->f_ctime = date_dos2unix(server, date, time);
2252
2253 date = WVAL(resp_data, 4 + off_date);
2254 time = WVAL(resp_data, 4 + off_time);
2255 attr->f_atime = date_dos2unix(server, date, time);
2256
2257 date = WVAL(resp_data, 8 + off_date);
2258 time = WVAL(resp_data, 8 + off_time);
2259 attr->f_mtime = date_dos2unix(server, date, time);
2260 #ifdef SMBFS_DEBUG_TIMESTAMP
2261 printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
2262 DENTRY_PATH(dir), date, time, attr->f_mtime);
2263 #endif
2264 attr->f_size = DVAL(resp_data, 12);
2265 attr->attr = WVAL(resp_data, 20);
2266 result = 0;
2267
2268 out:
2269 return result;
2270 }
2271
2272 /*
2273 * Note: called with the server locked
2274 */
2275 static int
2276 smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir,
2277 struct smb_fattr *fattr)
2278 {
2279 int result;
2280 struct inode *inode = dir->d_inode;
2281
2282 smb_init_dirent(server, fattr);
2283
2284 /*
2285 * Select whether to use core or trans2 getattr.
2286 * Win 95 appears to break with the trans2 getattr.
2287 */
2288 if (server->opt.protocol < SMB_PROTOCOL_LANMAN2 ||
2289 (server->mnt->flags & (SMB_MOUNT_OLDATTR|SMB_MOUNT_WIN95)) ) {
2290 result = smb_proc_getattr_core(server, dir, fattr);
2291 } else {
2292 if (server->mnt->flags & SMB_MOUNT_DIRATTR)
2293 result = smb_proc_getattr_ff(server, dir, fattr);
2294 else
2295 result = smb_proc_getattr_trans2(server, dir, fattr);
2296 }
2297
2298 /*
2299 * None of the getattr versions here can make win9x return the right
2300 * filesize if there are changes made to an open file.
2301 * A seek-to-end does return the right size, but we only need to do
2302 * that on files we have written.
2303 */
2304 if (server->mnt->flags & SMB_MOUNT_WIN95 &&
2305 inode &&
2306 inode->u.smbfs_i.flags & SMB_F_LOCALWRITE &&
2307 smb_is_open(inode))
2308 {
2309 __u16 fileid = inode->u.smbfs_i.fileid;
2310 fattr->f_size = smb_proc_seek(server, fileid, 2, 0);
2311 }
2312
2313 smb_finish_dirent(server, fattr);
2314 return result;
2315 }
2316
2317 int
2318 smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
2319 {
2320 struct smb_sb_info *server = server_from_dentry(dir);
2321 int result;
2322
2323 smb_lock_server(server);
2324 result = smb_proc_do_getattr(server, dir, fattr);
2325 smb_unlock_server(server);
2326 return result;
2327 }
2328
2329
2330 /*
2331 * Called with the server locked. Because of bugs in the
2332 * core protocol, we use this only to set attributes. See
2333 * smb_proc_settime() below for timestamp handling.
2334 *
2335 * Bugs Noted:
2336 * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail
2337 * with an undocumented error (ERRDOS code 50). Setting
2338 * mtime to 0 allows the attributes to be set.
2339 * (2) The extra parameters following the name string aren't
2340 * in the CIFS docs, but seem to be necessary for operation.
2341 */
2342 static int
2343 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
2344 __u16 attr)
2345 {
2346 char *p;
2347 int result;
2348
2349 retry:
2350 p = smb_setup_header(server, SMBsetatr, 8, 0);
2351 WSET(server->packet, smb_vwv0, attr);
2352 DSET(server->packet, smb_vwv1, 0); /* mtime */
2353 WSET(server->packet, smb_vwv3, 0); /* reserved values */
2354 WSET(server->packet, smb_vwv4, 0);
2355 WSET(server->packet, smb_vwv5, 0);
2356 WSET(server->packet, smb_vwv6, 0);
2357 WSET(server->packet, smb_vwv7, 0);
2358 *p++ = 4;
2359 result = smb_encode_path(server, p, dentry, NULL);
2360 if (result < 0)
2361 goto out;
2362 p += result;
2363 *p++ = 4;
2364 *p++ = 0;
2365 smb_setup_bcc(server, p);
2366
2367 result = smb_request_ok(server, SMBsetatr, 0, 0);
2368 if (result < 0) {
2369 if (smb_retry(server))
2370 goto retry;
2371 goto out;
2372 }
2373 result = 0;
2374 out:
2375 return result;
2376 }
2377
2378 /*
2379 * Because of bugs in the trans2 setattr messages, we must set
2380 * attributes and timestamps separately. The core SMBsetatr
2381 * message seems to be the only reliable way to set attributes.
2382 */
2383 int
2384 smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr)
2385 {
2386 struct smb_sb_info *server = server_from_dentry(dir);
2387 int result;
2388
2389 VERBOSE("setting %s/%s, open=%d\n",
2390 DENTRY_PATH(dir), smb_is_open(dir->d_inode));
2391 smb_lock_server(server);
2392 result = smb_proc_setattr_core(server, dir, fattr->attr);
2393 smb_unlock_server(server);
2394 return result;
2395 }
2396
2397 /*
2398 * Called with the server locked. Sets the timestamps for an
2399 * file open with write permissions.
2400 */
2401 static int
2402 smb_proc_setattr_ext(struct smb_sb_info *server,
2403 struct inode *inode, struct smb_fattr *fattr)
2404 {
2405 __u16 date, time;
2406 int result;
2407
2408 retry:
2409 smb_setup_header(server, SMBsetattrE, 7, 0);
2410 WSET(server->packet, smb_vwv0, inode->u.smbfs_i.fileid);
2411 /* We don't change the creation time */
2412 WSET(server->packet, smb_vwv1, 0);
2413 WSET(server->packet, smb_vwv2, 0);
2414 date_unix2dos(server, fattr->f_atime, &date, &time);
2415 WSET(server->packet, smb_vwv3, date);
2416 WSET(server->packet, smb_vwv4, time);
2417 date_unix2dos(server, fattr->f_mtime, &date, &time);
2418 WSET(server->packet, smb_vwv5, date);
2419 WSET(server->packet, smb_vwv6, time);
2420 #ifdef SMBFS_DEBUG_TIMESTAMP
2421 printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n",
2422 date, time, fattr->f_mtime);
2423 #endif
2424
2425 result = smb_request_ok(server, SMBsetattrE, 0, 0);
2426 if (result < 0) {
2427 if (smb_retry(server))
2428 goto retry;
2429 goto out;
2430 }
2431 result = 0;
2432 out:
2433 return result;
2434 }
2435
2436 /*
2437 * Note: called with the server locked.
2438 *
2439 * Bugs Noted:
2440 * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't
2441 * set the file's attribute flags.
2442 */
2443 static int
2444 smb_proc_setattr_trans2(struct smb_sb_info *server,
2445 struct dentry *dir, struct smb_fattr *fattr)
2446 {
2447 __u16 date, time;
2448 char *p, *param = server->temp_buf;
2449 unsigned char *resp_data = NULL;
2450 unsigned char *resp_param = NULL;
2451 int resp_data_len = 0;
2452 int resp_param_len = 0;
2453 int result;
2454 char data[26];
2455
2456 retry:
2457 WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */
2458 DSET(param, 2, 0);
2459 result = smb_encode_path(server, param + 6, dir, NULL);
2460 if (result < 0)
2461 goto out;
2462 p = param + 6 + result;
2463
2464 WSET(data, 0, 0); /* creation time */
2465 WSET(data, 2, 0);
2466 date_unix2dos(server, fattr->f_atime, &date, &time);
2467 WSET(data, 4, date);
2468 WSET(data, 6, time);
2469 date_unix2dos(server, fattr->f_mtime, &date, &time);
2470 WSET(data, 8, date);
2471 WSET(data, 10, time);
2472 #ifdef SMBFS_DEBUG_TIMESTAMP
2473 printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
2474 DENTRY_PATH(dir), date, time, fattr->f_mtime);
2475 #endif
2476 DSET(data, 12, 0); /* size */
2477 DSET(data, 16, 0); /* blksize */
2478 WSET(data, 20, 0); /* attr */
2479 DSET(data, 22, 0); /* ULONG EA size */
2480
2481 result = smb_trans2_request(server, TRANSACT2_SETPATHINFO,
2482 26, data, p - param, param,
2483 &resp_data_len, &resp_data,
2484 &resp_param_len, &resp_param);
2485 if (result < 0)
2486 {
2487 if (smb_retry(server))
2488 goto retry;
2489 goto out;
2490 }
2491 result = 0;
2492 if (server->rcls != 0)
2493 result = -smb_errno(server);
2494
2495 out:
2496 return result;
2497 }
2498
2499 /*
2500 * Set the modify and access timestamps for a file.
2501 *
2502 * Incredibly enough, in all of SMB there is no message to allow
2503 * setting both attributes and timestamps at once.
2504 *
2505 * Bugs Noted:
2506 * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message
2507 * with info level 1 (INFO_STANDARD).
2508 * (2) Win 95 seems not to support setting directory timestamps.
2509 * (3) Under the core protocol apparently the only way to set the
2510 * timestamp is to open and close the file.
2511 */
2512 int
2513 smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
2514 {
2515 struct smb_sb_info *server = server_from_dentry(dentry);
2516 struct inode *inode = dentry->d_inode;
2517 int result;
2518
2519 VERBOSE("setting %s/%s, open=%d\n",
2520 DENTRY_PATH(dentry), smb_is_open(inode));
2521
2522 smb_lock_server(server);
2523 /* setting the time on a Win95 server fails (tridge) */
2524 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 &&
2525 !(server->mnt->flags & SMB_MOUNT_WIN95)) {
2526 if (smb_is_open(inode) &&
2527 inode->u.smbfs_i.access != SMB_O_RDONLY)
2528 result = smb_proc_setattr_ext(server, inode, fattr);
2529 else
2530 result = smb_proc_setattr_trans2(server, dentry, fattr);
2531 } else {
2532 /*
2533 * Fail silently on directories ... timestamp can't be set?
2534 */
2535 result = 0;
2536 if (S_ISREG(inode->i_mode)) {
2537 /*
2538 * Set the mtime by opening and closing the file.
2539 * Note that the file is opened read-only, but this
2540 * still allows us to set the date (tridge)
2541 */
2542 result = -EACCES;
2543 if (!smb_is_open(inode))
2544 smb_proc_open(server, dentry, SMB_O_RDONLY);
2545 if (smb_is_open(inode)) {
2546 inode->i_mtime = fattr->f_mtime;
2547 result = smb_proc_close_inode(server, inode);
2548 }
2549 }
2550 }
2551
2552 smb_unlock_server(server);
2553 return result;
2554 }
2555
2556 int
2557 smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
2558 {
2559 struct smb_sb_info *server = &(sb->u.smbfs_sb);
2560 int result;
2561 char *p;
2562
2563 smb_lock_server(server);
2564
2565 retry:
2566 smb_setup_header(server, SMBdskattr, 0, 0);
2567
2568 if ((result = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
2569 if (smb_retry(server))
2570 goto retry;
2571 goto out;
2572 }
2573 p = SMB_VWV(server->packet);
2574 attr->f_blocks = WVAL(p, 0);
2575 attr->f_bsize = WVAL(p, 2) * WVAL(p, 4);
2576 attr->f_bavail = attr->f_bfree = WVAL(p, 6);
2577 result = 0;
2578
2579 out:
2580 smb_unlock_server(server);
2581 return result;
2582 }
2583
2584 int
2585 smb_proc_disconnect(struct smb_sb_info *server)
2586 {
2587 int result;
2588 smb_lock_server(server);
2589 smb_setup_header(server, SMBtdis, 0, 0);
2590 result = smb_request_ok(server, SMBtdis, 0, 0);
2591 smb_unlock_server(server);
2592 return result;
2593 }
2594