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 ¶m[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 ¶m[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 ¶m[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 ¶m[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 ¶m[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 ¶m[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 ¶m[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 ¶m[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 ¶m[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 ¶m[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 ¶m[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