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