Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (25 commits)
[CIFS] Fix authentication choice so we do not force NTLMv2 unless the
[CIFS] Fix alignment of unicode strings in previous patch
[CIFS] Fix allocation of buffers for new session setup routine to allow
[CIFS] Remove calls to to take f_owner.lock
[CIFS] remove some redundant null pointer checks
[CIFS] Fix compile warning when CONFIG_CIFS_EXPERIMENTAL is off
[CIFS] Enable sec flags on mount for cifs (part one)
[CIFS] Fix suspend/resume problem which causes EIO on subsequent access to
[CIFS] fix minor compile warning when config_cifs_weak_security is off
[CIFS] NTLMv2 support part 5
[CIFS] Add support for readdir to legacy servers
[CIFS] NTLMv2 support part 4
[CIFS] NTLMv2 support part 3
[CIFS] NTLMv2 support part 2
[CIFS] Fix mask so can set new cifs security flags properly
CIFS] Support for older servers which require plaintext passwords - part 2
[CIFS] Support for older servers which require plaintext passwords
[CIFS] Fix mapping of old SMB return code Invalid Net Name so it is
[CIFS] Missing brace
[CIFS] Do not overwrite aops
...

+1544 -826
+38 -2
fs/Kconfig
··· 1722 mounted by the cifs client to be displayed in /proc/fs/cifs/Stats 1723 1724 config CIFS_STATS2 1725 - bool "CIFS extended statistics" 1726 depends on CIFS_STATS 1727 help 1728 Enabling this option will allow more detailed statistics on SMB ··· 1734 1735 Unless you are a developer or are doing network performance analysis 1736 or tuning, say N. 1737 1738 config CIFS_XATTR 1739 bool "CIFS extended attributes" ··· 1789 (such as Samba 3.10 and later) which can negotiate 1790 CIFS POSIX ACL support. If unsure, say N. 1791 1792 config CIFS_EXPERIMENTAL 1793 bool "CIFS Experimental Features (EXPERIMENTAL)" 1794 depends on CIFS && EXPERIMENTAL ··· 1814 If unsure, say N. 1815 1816 config CIFS_UPCALL 1817 - bool "CIFS Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" 1818 depends on CIFS_EXPERIMENTAL 1819 select CONNECTOR 1820 help
··· 1722 mounted by the cifs client to be displayed in /proc/fs/cifs/Stats 1723 1724 config CIFS_STATS2 1725 + bool "Extended statistics" 1726 depends on CIFS_STATS 1727 help 1728 Enabling this option will allow more detailed statistics on SMB ··· 1734 1735 Unless you are a developer or are doing network performance analysis 1736 or tuning, say N. 1737 + 1738 + config CIFS_WEAK_PW_HASH 1739 + bool "Support legacy servers which use weaker LANMAN security" 1740 + depends on CIFS 1741 + help 1742 + Modern CIFS servers including Samba and most Windows versions 1743 + (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos) 1744 + security mechanisms. These hash the password more securely 1745 + than the mechanisms used in the older LANMAN version of the 1746 + SMB protocol needed to establish sessions with old SMB servers. 1747 + 1748 + Enabling this option allows the cifs module to mount to older 1749 + LANMAN based servers such as OS/2 and Windows 95, but such 1750 + mounts may be less secure than mounts using NTLM or more recent 1751 + security mechanisms if you are on a public network. Unless you 1752 + have a need to access old SMB servers (and are on a private 1753 + network) you probably want to say N. Even if this support 1754 + is enabled in the kernel build, they will not be used 1755 + automatically. At runtime LANMAN mounts are disabled but 1756 + can be set to required (or optional) either in 1757 + /proc/fs/cifs (see fs/cifs/README for more detail) or via an 1758 + option on the mount command. This support is disabled by 1759 + default in order to reduce the possibility of a downgrade 1760 + attack. 1761 + 1762 + If unsure, say N. 1763 1764 config CIFS_XATTR 1765 bool "CIFS extended attributes" ··· 1763 (such as Samba 3.10 and later) which can negotiate 1764 CIFS POSIX ACL support. If unsure, say N. 1765 1766 + config CIFS_DEBUG2 1767 + bool "Enable additional CIFS debugging routines" 1768 + help 1769 + Enabling this option adds a few more debugging routines 1770 + to the cifs code which slightly increases the size of 1771 + the cifs module and can cause additional logging of debug 1772 + messages in some error paths, slowing performance. This 1773 + option can be turned off unless you are debugging 1774 + cifs problems. If unsure, say N. 1775 + 1776 config CIFS_EXPERIMENTAL 1777 bool "CIFS Experimental Features (EXPERIMENTAL)" 1778 depends on CIFS && EXPERIMENTAL ··· 1778 If unsure, say N. 1779 1780 config CIFS_UPCALL 1781 + bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" 1782 depends on CIFS_EXPERIMENTAL 1783 select CONNECTOR 1784 help
+16 -1
fs/cifs/CHANGES
··· 1 Version 1.43 2 ------------ 3 POSIX locking to servers which support CIFS POSIX Extensions 4 (disabled by default controlled by proc/fs/cifs/Experimental). 5 Handle conversion of long share names (especially Asian languages) 6 - to Unicode during mount. 7 8 Version 1.42 9 ------------
··· 1 + Version 1.44 2 + ------------ 3 + Rewritten sessionsetup support, including support for legacy SMB 4 + session setup needed for OS/2 and older servers such as Windows 95 and 98. 5 + Fix oops on ls to OS/2 servers. Add support for level 1 FindFirst 6 + so we can do search (ls etc.) to OS/2. Do not send NTCreateX 7 + or recent levels of FindFirst unless server says it supports NT SMBs 8 + (instead use legacy equivalents from LANMAN dialect). Fix to allow 9 + NTLMv2 authentication support (now can use stronger password hashing 10 + on mount if corresponding /proc/fs/cifs/SecurityFlags is set (0x4004). 11 + Allow override of global cifs security flags on mount via "sec=" option(s). 12 + 13 Version 1.43 14 ------------ 15 POSIX locking to servers which support CIFS POSIX Extensions 16 (disabled by default controlled by proc/fs/cifs/Experimental). 17 Handle conversion of long share names (especially Asian languages) 18 + to Unicode during mount. Fix memory leak in sess struct on reconnect. 19 + Fix rare oops after acpi suspend. Fix O_TRUNC opens to overwrite on 20 + cifs open which helps rare case when setpathinfo fails or server does 21 + not support it. 22 23 Version 1.42 24 ------------
+1 -1
fs/cifs/Makefile
··· 3 # 4 obj-$(CONFIG_CIFS) += cifs.o 5 6 - cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o ntlmssp.o
··· 3 # 4 obj-$(CONFIG_CIFS) += cifs.o 5 6 + cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o
+32 -7
fs/cifs/README
··· 443 SFU does). In the future the bottom 9 bits of the mode 444 mode also will be emulated using queries of the security 445 descriptor (ACL). 446 - sec Security mode. Allowed values are: 447 none attempt to connection as a null user (no name) 448 krb5 Use Kerberos version 5 authentication 449 krb5i Use Kerberos authentication and packet signing ··· 456 server requires signing also can be the default) 457 ntlmv2 Use NTLMv2 password hashing 458 ntlmv2i Use NTLMv2 password hashing with packet signing 459 460 The mount.cifs mount helper also accepts a few mount options before -o 461 including: ··· 490 it. If set to two, cifs packet signing is 491 required even if the server considers packet 492 signing optional. (default 1) 493 cifsFYI If set to one, additional debug information is 494 logged to the system error log. (default 0) 495 - ExtendedSecurity If set to one, SPNEGO session establishment 496 - is allowed which enables more advanced 497 - secure CIFS session establishment (default 0) 498 - NTLMV2Enabled If set to one, more secure password hashes 499 - are used when the server supports them and 500 - when kerberos is not negotiated (default 0) 501 traceSMB If set to one, debug information is logged to the 502 system error log with the start of smb requests 503 and responses (default 0)
··· 443 SFU does). In the future the bottom 9 bits of the mode 444 mode also will be emulated using queries of the security 445 descriptor (ACL). 446 + sign Must use packet signing (helps avoid unwanted data modification 447 + by intermediate systems in the route). Note that signing 448 + does not work with lanman or plaintext authentication. 449 + sec Security mode. Allowed values are: 450 none attempt to connection as a null user (no name) 451 krb5 Use Kerberos version 5 authentication 452 krb5i Use Kerberos authentication and packet signing ··· 453 server requires signing also can be the default) 454 ntlmv2 Use NTLMv2 password hashing 455 ntlmv2i Use NTLMv2 password hashing with packet signing 456 + lanman (if configured in kernel config) use older 457 + lanman hash 458 459 The mount.cifs mount helper also accepts a few mount options before -o 460 including: ··· 485 it. If set to two, cifs packet signing is 486 required even if the server considers packet 487 signing optional. (default 1) 488 + SecurityFlags Flags which control security negotiation and 489 + also packet signing. Authentication (may/must) 490 + flags (e.g. for NTLM and/or NTLMv2) may be combined with 491 + the signing flags. Specifying two different password 492 + hashing mechanisms (as "must use") on the other hand 493 + does not make much sense. Default flags are 494 + 0x07007 495 + (NTLM, NTLMv2 and packet signing allowed). Maximum 496 + allowable flags if you want to allow mounts to servers 497 + using weaker password hashes is 0x37037 (lanman, 498 + plaintext, ntlm, ntlmv2, signing allowed): 499 + 500 + may use packet signing 0x00001 501 + must use packet signing 0x01001 502 + may use NTLM (most common password hash) 0x00002 503 + must use NTLM 0x02002 504 + may use NTLMv2 0x00004 505 + must use NTLMv2 0x04004 506 + may use Kerberos security (not implemented yet) 0x00008 507 + must use Kerberos (not implemented yet) 0x08008 508 + may use lanman (weak) password hash 0x00010 509 + must use lanman password hash 0x10010 510 + may use plaintext passwords 0x00020 511 + must use plaintext passwords 0x20020 512 + (reserved for future packet encryption) 0x00040 513 + 514 cifsFYI If set to one, additional debug information is 515 logged to the system error log. (default 0) 516 traceSMB If set to one, debug information is logged to the 517 system error log with the start of smb requests 518 and responses (default 0)
+5 -5
fs/cifs/asn1.c
··· 467 asn1_open(&ctx, security_blob, length); 468 469 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 470 - cFYI(1, ("Error decoding negTokenInit header ")); 471 return 0; 472 } else if ((cls != ASN1_APL) || (con != ASN1_CON) 473 || (tag != ASN1_EOC)) { ··· 495 } 496 497 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 498 - cFYI(1, ("Error decoding negTokenInit ")); 499 return 0; 500 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 501 || (tag != ASN1_EOC)) { ··· 505 } 506 507 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 508 - cFYI(1, ("Error decoding negTokenInit ")); 509 return 0; 510 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 511 || (tag != ASN1_SEQ)) { ··· 515 } 516 517 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 518 - cFYI(1, ("Error decoding 2nd part of negTokenInit ")); 519 return 0; 520 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 521 || (tag != ASN1_EOC)) { ··· 527 528 if (asn1_header_decode 529 (&ctx, &sequence_end, &cls, &con, &tag) == 0) { 530 - cFYI(1, ("Error decoding 2nd part of negTokenInit ")); 531 return 0; 532 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 533 || (tag != ASN1_SEQ)) {
··· 467 asn1_open(&ctx, security_blob, length); 468 469 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 470 + cFYI(1, ("Error decoding negTokenInit header")); 471 return 0; 472 } else if ((cls != ASN1_APL) || (con != ASN1_CON) 473 || (tag != ASN1_EOC)) { ··· 495 } 496 497 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 498 + cFYI(1, ("Error decoding negTokenInit")); 499 return 0; 500 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 501 || (tag != ASN1_EOC)) { ··· 505 } 506 507 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 508 + cFYI(1, ("Error decoding negTokenInit")); 509 return 0; 510 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 511 || (tag != ASN1_SEQ)) { ··· 515 } 516 517 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 518 + cFYI(1, ("Error decoding 2nd part of negTokenInit")); 519 return 0; 520 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 521 || (tag != ASN1_EOC)) { ··· 527 528 if (asn1_header_decode 529 (&ctx, &sequence_end, &cls, &con, &tag) == 0) { 530 + cFYI(1, ("Error decoding 2nd part of negTokenInit")); 531 return 0; 532 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 533 || (tag != ASN1_SEQ)) {
+107 -27
fs/cifs/cifs_debug.c
··· 39 char *charptr = data; 40 char buf[10], line[80]; 41 42 - printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n\n", 43 label, length, data); 44 for (i = 0; i < length; i += 16) { 45 line[0] = 0; ··· 57 } 58 } 59 60 #ifdef CONFIG_PROC_FS 61 static int 62 cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ··· 124 125 *beginBuffer = buf + offset; 126 127 - 128 length = 129 sprintf(buf, 130 "Display Internal CIFS Data Structures for Debugging\n" ··· 445 static write_proc_t traceSMB_write; 446 static read_proc_t multiuser_mount_read; 447 static write_proc_t multiuser_mount_write; 448 - static read_proc_t extended_security_read; 449 - static write_proc_t extended_security_write; 450 - static read_proc_t ntlmv2_enabled_read; 451 static write_proc_t ntlmv2_enabled_write; 452 static read_proc_t packet_signing_enabled_read; 453 - static write_proc_t packet_signing_enabled_write; 454 static read_proc_t experimEnabled_read; 455 static write_proc_t experimEnabled_write; 456 static read_proc_t linuxExtensionsEnabled_read; ··· 508 pde->write_proc = multiuser_mount_write; 509 510 pde = 511 - create_proc_read_entry("ExtendedSecurity", 0, proc_fs_cifs, 512 - extended_security_read, NULL); 513 if (pde) 514 - pde->write_proc = extended_security_write; 515 516 pde = 517 create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs, ··· 519 if (pde) 520 pde->write_proc = lookupFlag_write; 521 522 - pde = 523 create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs, 524 ntlmv2_enabled_read, NULL); 525 if (pde) ··· 529 create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs, 530 packet_signing_enabled_read, NULL); 531 if (pde) 532 - pde->write_proc = packet_signing_enabled_write; 533 } 534 535 void ··· 546 #endif 547 remove_proc_entry("MultiuserMount", proc_fs_cifs); 548 remove_proc_entry("OplockEnabled", proc_fs_cifs); 549 - remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); 550 - remove_proc_entry("ExtendedSecurity",proc_fs_cifs); 551 - remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); 552 remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs); 553 remove_proc_entry("Experimental",proc_fs_cifs); 554 remove_proc_entry("LookupCacheEnabled",proc_fs_cifs); ··· 832 } 833 834 static int 835 - extended_security_read(char *page, char **start, off_t off, 836 int count, int *eof, void *data) 837 { 838 int len; 839 840 - len = sprintf(page, "%d\n", extended_security); 841 842 len -= off; 843 *start = page + off; ··· 853 return len; 854 } 855 static int 856 - extended_security_write(struct file *file, const char __user *buffer, 857 unsigned long count, void *data) 858 { 859 char c; 860 - int rc; 861 862 - rc = get_user(c, buffer); 863 - if (rc) 864 - return rc; 865 - if (c == '0' || c == 'n' || c == 'N') 866 - extended_security = 0; 867 - else if (c == '1' || c == 'y' || c == 'Y') 868 - extended_security = 1; 869 870 return count; 871 } 872 873 - static int 874 ntlmv2_enabled_read(char *page, char **start, off_t off, 875 int count, int *eof, void *data) 876 { ··· 933 ntlmv2_support = 0; 934 else if (c == '1' || c == 'y' || c == 'Y') 935 ntlmv2_support = 1; 936 937 return count; 938 } ··· 978 sign_CIFS_PDUs = 2; 979 980 return count; 981 - } 982 983 984 #endif
··· 39 char *charptr = data; 40 char buf[10], line[80]; 41 42 + printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n", 43 label, length, data); 44 for (i = 0; i < length; i += 16) { 45 line[0] = 0; ··· 57 } 58 } 59 60 + #ifdef CONFIG_CIFS_DEBUG2 61 + void cifs_dump_detail(struct smb_hdr * smb) 62 + { 63 + cERROR(1,("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", 64 + smb->Command, smb->Status.CifsError, 65 + smb->Flags, smb->Flags2, smb->Mid, smb->Pid)); 66 + cERROR(1,("smb buf %p len %d", smb, smbCalcSize_LE(smb))); 67 + } 68 + 69 + 70 + void cifs_dump_mids(struct TCP_Server_Info * server) 71 + { 72 + struct list_head *tmp; 73 + struct mid_q_entry * mid_entry; 74 + 75 + if(server == NULL) 76 + return; 77 + 78 + cERROR(1,("Dump pending requests:")); 79 + spin_lock(&GlobalMid_Lock); 80 + list_for_each(tmp, &server->pending_mid_q) { 81 + mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 82 + if(mid_entry) { 83 + cERROR(1,("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d", 84 + mid_entry->midState, 85 + (int)mid_entry->command, 86 + mid_entry->pid, 87 + mid_entry->tsk, 88 + mid_entry->mid)); 89 + #ifdef CONFIG_CIFS_STATS2 90 + cERROR(1,("IsLarge: %d buf: %p time rcv: %ld now: %ld", 91 + mid_entry->largeBuf, 92 + mid_entry->resp_buf, 93 + mid_entry->when_received, 94 + jiffies)); 95 + #endif /* STATS2 */ 96 + cERROR(1,("IsMult: %d IsEnd: %d", mid_entry->multiRsp, 97 + mid_entry->multiEnd)); 98 + if(mid_entry->resp_buf) { 99 + cifs_dump_detail(mid_entry->resp_buf); 100 + cifs_dump_mem("existing buf: ", 101 + mid_entry->resp_buf, 102 + 62 /* fixme */); 103 + } 104 + 105 + } 106 + } 107 + spin_unlock(&GlobalMid_Lock); 108 + } 109 + #endif /* CONFIG_CIFS_DEBUG2 */ 110 + 111 #ifdef CONFIG_PROC_FS 112 static int 113 cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ··· 73 74 *beginBuffer = buf + offset; 75 76 length = 77 sprintf(buf, 78 "Display Internal CIFS Data Structures for Debugging\n" ··· 395 static write_proc_t traceSMB_write; 396 static read_proc_t multiuser_mount_read; 397 static write_proc_t multiuser_mount_write; 398 + static read_proc_t security_flags_read; 399 + static write_proc_t security_flags_write; 400 + /* static read_proc_t ntlmv2_enabled_read; 401 static write_proc_t ntlmv2_enabled_write; 402 static read_proc_t packet_signing_enabled_read; 403 + static write_proc_t packet_signing_enabled_write;*/ 404 static read_proc_t experimEnabled_read; 405 static write_proc_t experimEnabled_write; 406 static read_proc_t linuxExtensionsEnabled_read; ··· 458 pde->write_proc = multiuser_mount_write; 459 460 pde = 461 + create_proc_read_entry("SecurityFlags", 0, proc_fs_cifs, 462 + security_flags_read, NULL); 463 if (pde) 464 + pde->write_proc = security_flags_write; 465 466 pde = 467 create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs, ··· 469 if (pde) 470 pde->write_proc = lookupFlag_write; 471 472 + /* pde = 473 create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs, 474 ntlmv2_enabled_read, NULL); 475 if (pde) ··· 479 create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs, 480 packet_signing_enabled_read, NULL); 481 if (pde) 482 + pde->write_proc = packet_signing_enabled_write;*/ 483 } 484 485 void ··· 496 #endif 497 remove_proc_entry("MultiuserMount", proc_fs_cifs); 498 remove_proc_entry("OplockEnabled", proc_fs_cifs); 499 + /* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */ 500 + remove_proc_entry("SecurityFlags",proc_fs_cifs); 501 + /* remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); */ 502 remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs); 503 remove_proc_entry("Experimental",proc_fs_cifs); 504 remove_proc_entry("LookupCacheEnabled",proc_fs_cifs); ··· 782 } 783 784 static int 785 + security_flags_read(char *page, char **start, off_t off, 786 int count, int *eof, void *data) 787 { 788 int len; 789 790 + len = sprintf(page, "0x%x\n", extended_security); 791 792 len -= off; 793 *start = page + off; ··· 803 return len; 804 } 805 static int 806 + security_flags_write(struct file *file, const char __user *buffer, 807 unsigned long count, void *data) 808 { 809 + unsigned int flags; 810 + char flags_string[12]; 811 char c; 812 813 + if((count < 1) || (count > 11)) 814 + return -EINVAL; 815 816 + memset(flags_string, 0, 12); 817 + 818 + if(copy_from_user(flags_string, buffer, count)) 819 + return -EFAULT; 820 + 821 + if(count < 3) { 822 + /* single char or single char followed by null */ 823 + c = flags_string[0]; 824 + if (c == '0' || c == 'n' || c == 'N') 825 + extended_security = CIFSSEC_DEF; /* default */ 826 + else if (c == '1' || c == 'y' || c == 'Y') 827 + extended_security = CIFSSEC_MAX; 828 + return count; 829 + } 830 + /* else we have a number */ 831 + 832 + flags = simple_strtoul(flags_string, NULL, 0); 833 + 834 + cFYI(1,("sec flags 0x%x", flags)); 835 + 836 + if(flags <= 0) { 837 + cERROR(1,("invalid security flags %s",flags_string)); 838 + return -EINVAL; 839 + } 840 + 841 + if(flags & ~CIFSSEC_MASK) { 842 + cERROR(1,("attempt to set unsupported security flags 0x%x", 843 + flags & ~CIFSSEC_MASK)); 844 + return -EINVAL; 845 + } 846 + /* flags look ok - update the global security flags for cifs module */ 847 + extended_security = flags; 848 return count; 849 } 850 851 + /* static int 852 ntlmv2_enabled_read(char *page, char **start, off_t off, 853 int count, int *eof, void *data) 854 { ··· 855 ntlmv2_support = 0; 856 else if (c == '1' || c == 'y' || c == 'Y') 857 ntlmv2_support = 1; 858 + else if (c == '2') 859 + ntlmv2_support = 2; 860 861 return count; 862 } ··· 898 sign_CIFS_PDUs = 2; 899 900 return count; 901 + } */ 902 903 904 #endif
+4
fs/cifs/cifs_debug.h
··· 24 #define _H_CIFS_DEBUG 25 26 void cifs_dump_mem(char *label, void *data, int length); 27 extern int traceSMB; /* flag which enables the function below */ 28 void dump_smb(struct smb_hdr *, int); 29 #define CIFS_INFO 0x01
··· 24 #define _H_CIFS_DEBUG 25 26 void cifs_dump_mem(char *label, void *data, int length); 27 + #ifdef CONFIG_CIFS_DEBUG2 28 + void cifs_dump_detail(struct smb_hdr *); 29 + void cifs_dump_mids(struct TCP_Server_Info *); 30 + #endif 31 extern int traceSMB; /* flag which enables the function below */ 32 void dump_smb(struct smb_hdr *, int); 33 #define CIFS_INFO 0x01
+1
fs/cifs/cifs_unicode.c
··· 22 #include "cifs_unicode.h" 23 #include "cifs_uniupr.h" 24 #include "cifspdu.h" 25 #include "cifs_debug.h" 26 27 /*
··· 22 #include "cifs_unicode.h" 23 #include "cifs_uniupr.h" 24 #include "cifspdu.h" 25 + #include "cifsglob.h" 26 #include "cifs_debug.h" 27 28 /*
+131 -9
fs/cifs/cifsencrypt.c
··· 26 #include "md5.h" 27 #include "cifs_unicode.h" 28 #include "cifsproto.h" 29 30 /* Calculate and return the CIFS signature based on the mac key and the smb pdu */ 31 /* the 16 byte signature must be allocated by the caller */ ··· 37 38 extern void mdfour(unsigned char *out, unsigned char *in, int n); 39 extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 40 41 static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, 42 const char * key, char * signature) ··· 49 return -EINVAL; 50 51 MD5Init(&context); 52 - MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); 53 MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); 54 MD5Final(signature,&context); 55 return 0; ··· 94 return -EINVAL; 95 96 MD5Init(&context); 97 - MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); 98 for(i=0;i<n_vec;i++) { 99 if(iov[i].iov_base == NULL) { 100 cERROR(1,("null iovec entry")); ··· 208 209 E_md4hash(password, temp_key); 210 mdfour(key,temp_key,16); 211 - memcpy(key+16,rn, CIFS_SESSION_KEY_SIZE); 212 return 0; 213 } 214 215 - int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_info) 216 { 217 char temp_hash[16]; 218 struct HMACMD5Context ctx; ··· 230 user_name_len = strlen(ses->userName); 231 if(user_name_len > MAX_USERNAME_SIZE) 232 return -EINVAL; 233 dom_name_len = strlen(ses->domainName); 234 if(dom_name_len > MAX_USERNAME_SIZE) 235 return -EINVAL; ··· 266 kfree(unicode_buf); 267 return 0; 268 } 269 - void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response) 270 { 271 struct HMACMD5Context context; 272 memcpy(v2_session_response + 8, ses->server->cryptKey,8); 273 - /* gen_blob(v2_session_response + 16); */ 274 hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context); 275 276 - hmac_md5_update(ses->server->cryptKey,8,&context); 277 - /* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */ 278 279 hmac_md5_final(v2_session_response,&context); 280 - cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); /* BB removeme BB */ 281 }
··· 26 #include "md5.h" 27 #include "cifs_unicode.h" 28 #include "cifsproto.h" 29 + #include <linux/ctype.h> 30 + #include <linux/random.h> 31 32 /* Calculate and return the CIFS signature based on the mac key and the smb pdu */ 33 /* the 16 byte signature must be allocated by the caller */ ··· 35 36 extern void mdfour(unsigned char *out, unsigned char *in, int n); 37 extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 38 + extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, 39 + unsigned char *p24); 40 41 static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, 42 const char * key, char * signature) ··· 45 return -EINVAL; 46 47 MD5Init(&context); 48 + MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); 49 MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); 50 MD5Final(signature,&context); 51 return 0; ··· 90 return -EINVAL; 91 92 MD5Init(&context); 93 + MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); 94 for(i=0;i<n_vec;i++) { 95 if(iov[i].iov_base == NULL) { 96 cERROR(1,("null iovec entry")); ··· 204 205 E_md4hash(password, temp_key); 206 mdfour(key,temp_key,16); 207 + memcpy(key+16,rn, CIFS_SESS_KEY_SIZE); 208 return 0; 209 } 210 211 + int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, 212 + const struct nls_table * nls_info) 213 { 214 char temp_hash[16]; 215 struct HMACMD5Context ctx; ··· 225 user_name_len = strlen(ses->userName); 226 if(user_name_len > MAX_USERNAME_SIZE) 227 return -EINVAL; 228 + if(ses->domainName == NULL) 229 + return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ 230 dom_name_len = strlen(ses->domainName); 231 if(dom_name_len > MAX_USERNAME_SIZE) 232 return -EINVAL; ··· 259 kfree(unicode_buf); 260 return 0; 261 } 262 + 263 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 264 + void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key) 265 + { 266 + int i; 267 + char password_with_pad[CIFS_ENCPWD_SIZE]; 268 + 269 + if(ses->server == NULL) 270 + return; 271 + 272 + memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); 273 + strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); 274 + 275 + if((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0) 276 + if(extended_security & CIFSSEC_MAY_PLNTXT) { 277 + memcpy(lnm_session_key, password_with_pad, CIFS_ENCPWD_SIZE); 278 + return; 279 + } 280 + 281 + /* calculate old style session key */ 282 + /* calling toupper is less broken than repeatedly 283 + calling nls_toupper would be since that will never 284 + work for UTF8, but neither handles multibyte code pages 285 + but the only alternative would be converting to UCS-16 (Unicode) 286 + (using a routine something like UniStrupr) then 287 + uppercasing and then converting back from Unicode - which 288 + would only worth doing it if we knew it were utf8. Basically 289 + utf8 and other multibyte codepages each need their own strupper 290 + function since a byte at a time will ont work. */ 291 + 292 + for(i = 0; i < CIFS_ENCPWD_SIZE; i++) { 293 + password_with_pad[i] = toupper(password_with_pad[i]); 294 + } 295 + 296 + SMBencrypt(password_with_pad, ses->server->cryptKey, lnm_session_key); 297 + /* clear password before we return/free memory */ 298 + memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); 299 + } 300 + #endif /* CIFS_WEAK_PW_HASH */ 301 + 302 + static int calc_ntlmv2_hash(struct cifsSesInfo *ses, 303 + const struct nls_table * nls_cp) 304 + { 305 + int rc = 0; 306 + int len; 307 + char nt_hash[16]; 308 + struct HMACMD5Context * pctxt; 309 + wchar_t * user; 310 + wchar_t * domain; 311 + 312 + pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); 313 + 314 + if(pctxt == NULL) 315 + return -ENOMEM; 316 + 317 + /* calculate md4 hash of password */ 318 + E_md4hash(ses->password, nt_hash); 319 + 320 + /* convert Domainname to unicode and uppercase */ 321 + hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); 322 + 323 + /* convert ses->userName to unicode and uppercase */ 324 + len = strlen(ses->userName); 325 + user = kmalloc(2 + (len * 2), GFP_KERNEL); 326 + if(user == NULL) 327 + goto calc_exit_2; 328 + len = cifs_strtoUCS(user, ses->userName, len, nls_cp); 329 + UniStrupr(user); 330 + hmac_md5_update((char *)user, 2*len, pctxt); 331 + 332 + /* convert ses->domainName to unicode and uppercase */ 333 + if(ses->domainName) { 334 + len = strlen(ses->domainName); 335 + 336 + domain = kmalloc(2 + (len * 2), GFP_KERNEL); 337 + if(domain == NULL) 338 + goto calc_exit_1; 339 + len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp); 340 + UniStrupr(domain); 341 + 342 + hmac_md5_update((char *)domain, 2*len, pctxt); 343 + 344 + kfree(domain); 345 + } 346 + calc_exit_1: 347 + kfree(user); 348 + calc_exit_2: 349 + /* BB FIXME what about bytes 24 through 40 of the signing key? 350 + compare with the NTLM example */ 351 + hmac_md5_final(ses->server->mac_signing_key, pctxt); 352 + 353 + return rc; 354 + } 355 + 356 + void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf, 357 + const struct nls_table * nls_cp) 358 + { 359 + int rc; 360 + struct ntlmv2_resp * buf = (struct ntlmv2_resp *)resp_buf; 361 + 362 + buf->blob_signature = cpu_to_le32(0x00000101); 363 + buf->reserved = 0; 364 + buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 365 + get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 366 + buf->reserved2 = 0; 367 + buf->names[0].type = 0; 368 + buf->names[0].length = 0; 369 + 370 + /* calculate buf->ntlmv2_hash */ 371 + rc = calc_ntlmv2_hash(ses, nls_cp); 372 + if(rc) 373 + cERROR(1,("could not get v2 hash rc %d",rc)); 374 + CalcNTLMv2_response(ses, resp_buf); 375 + } 376 + 377 + void CalcNTLMv2_response(const struct cifsSesInfo * ses, char * v2_session_response) 378 { 379 struct HMACMD5Context context; 380 + /* rest of v2 struct already generated */ 381 memcpy(v2_session_response + 8, ses->server->cryptKey,8); 382 hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context); 383 384 + hmac_md5_update(v2_session_response+8, 385 + sizeof(struct ntlmv2_resp) - 8, &context); 386 387 hmac_md5_final(v2_session_response,&context); 388 + /* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 389 }
+3 -3
fs/cifs/cifsfs.c
··· 56 unsigned int linuxExtEnabled = 1; 57 unsigned int lookupCacheEnabled = 1; 58 unsigned int multiuser_mount = 0; 59 - unsigned int extended_security = 0; 60 - unsigned int ntlmv2_support = 0; 61 unsigned int sign_CIFS_PDUs = 1; 62 extern struct task_struct * oplockThread; /* remove sparse warning */ 63 struct task_struct * oplockThread = NULL; ··· 908 struct cifsSesInfo *ses; 909 910 do { 911 - if(try_to_freeze()) 912 continue; 913 set_current_state(TASK_INTERRUPTIBLE); 914 schedule_timeout(15*HZ);
··· 56 unsigned int linuxExtEnabled = 1; 57 unsigned int lookupCacheEnabled = 1; 58 unsigned int multiuser_mount = 0; 59 + unsigned int extended_security = CIFSSEC_DEF; 60 + /* unsigned int ntlmv2_support = 0; */ 61 unsigned int sign_CIFS_PDUs = 1; 62 extern struct task_struct * oplockThread; /* remove sparse warning */ 63 struct task_struct * oplockThread = NULL; ··· 908 struct cifsSesInfo *ses; 909 910 do { 911 + if (try_to_freeze()) 912 continue; 913 set_current_state(TASK_INTERRUPTIBLE); 914 schedule_timeout(15*HZ);
+2 -1
fs/cifs/cifsfs.h
··· 33 #endif 34 35 extern struct address_space_operations cifs_addr_ops; 36 37 /* Functions related to super block operations */ 38 extern struct super_operations cifs_super_ops; ··· 100 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 101 extern int cifs_ioctl (struct inode * inode, struct file * filep, 102 unsigned int command, unsigned long arg); 103 - #define CIFS_VERSION "1.43" 104 #endif /* _CIFSFS_H */
··· 33 #endif 34 35 extern struct address_space_operations cifs_addr_ops; 36 + extern struct address_space_operations cifs_addr_ops_smallbuf; 37 38 /* Functions related to super block operations */ 39 extern struct super_operations cifs_super_ops; ··· 99 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 100 extern int cifs_ioctl (struct inode * inode, struct file * filep, 101 unsigned int command, unsigned long arg); 102 + #define CIFS_VERSION "1.44" 103 #endif /* _CIFSFS_H */
+46 -23
fs/cifs/cifsglob.h
··· 88 }; 89 90 enum securityEnum { 91 - NTLM = 0, /* Legacy NTLM012 auth with NTLM hash */ 92 NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ 93 RawNTLMSSP, /* NTLMSSP without SPNEGO */ 94 NTLMSSP, /* NTLMSSP via SPNEGO */ ··· 158 /* 16th byte of RFC1001 workstation name is always null */ 159 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; 160 __u32 sequence_number; /* needed for CIFS PDU signature */ 161 - char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; 162 }; 163 164 /* ··· 180 struct cifsSesInfo { 181 struct list_head cifsSessionList; 182 struct semaphore sesSem; 183 struct cifsUidInfo *uidInfo; /* pointer to user info */ 184 struct TCP_Server_Info *server; /* pointer to server info */ 185 atomic_t inUse; /* # of mounts (tree connections) on this ses */ 186 enum statusEnum status; 187 __u16 ipc_tid; /* special tid for connection to IPC share */ 188 __u16 flags; 189 char *serverOS; /* name of operating system underlying server */ ··· 198 char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for 199 TCP names - will ipv6 and sctp addresses fit? */ 200 char userName[MAX_USERNAME_SIZE + 1]; 201 - char domainName[MAX_USERNAME_SIZE + 1]; 202 char * password; 203 }; 204 /* session flags */ ··· 213 struct list_head openFileList; 214 struct semaphore tconSem; 215 struct cifsSesInfo *ses; /* pointer to session associated with */ 216 - char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource (in ASCII not UTF) */ 217 char *nativeFileSystem; 218 __u16 tid; /* The 2 byte tree id */ 219 __u16 Flags; /* optional support bits */ 220 enum statusEnum tidStatus; 221 - atomic_t useCount; /* how many mounts (explicit or implicit) to this share */ 222 #ifdef CONFIG_CIFS_STATS 223 atomic_t num_smbs_sent; 224 atomic_t num_writes; ··· 258 spinlock_t stat_lock; 259 #endif /* CONFIG_CIFS_STATS */ 260 FILE_SYSTEM_DEVICE_INFO fsDevInfo; 261 - FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */ 262 FILE_SYSTEM_UNIX_INFO fsUnixInfo; 263 unsigned retry:1; 264 unsigned nocase:1; ··· 309 atomic_t wrtPending; /* handle in use - defer close */ 310 struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 311 char * search_resume_name; /* BB removeme BB */ 312 - unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */ 313 struct cifs_search_info srch_inf; 314 }; 315 ··· 394 struct smb_hdr *resp_buf; /* response buffer */ 395 int midState; /* wish this were enum but can not pass to wait_event */ 396 __u8 command; /* smb command code */ 397 - unsigned multiPart:1; /* multiple responses to one SMB request */ 398 unsigned largeBuf:1; /* if valid response, is pointer to large buf */ 399 - unsigned multiResp:1; /* multiple trans2 responses for one request */ 400 }; 401 402 struct oplock_q_entry { ··· 433 #define CIFS_LARGE_BUFFER 2 434 #define CIFS_IOVEC 4 /* array of response buffers */ 435 436 - /* Type of session setup needed */ 437 - #define CIFS_PLAINTEXT 0 438 - #define CIFS_LANMAN 1 439 - #define CIFS_NTLM 2 440 - #define CIFS_NTLMSSP_NEG 3 441 - #define CIFS_NTLMSSP_AUTH 4 442 - #define CIFS_SPNEGO_INIT 5 443 - #define CIFS_SPNEGO_TARG 6 444 445 /* 446 ***************************************************************** 447 * All constants go here ··· 523 GLOBAL_EXTERN struct list_head GlobalOplock_Q; 524 525 GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */ 526 - GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* Dir notify response queue */ 527 528 /* 529 * Global transaction id (XID) information 530 */ 531 GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */ 532 - GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ 533 GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ 534 - GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above and list operations */ 535 - /* on midQ entries */ 536 GLOBAL_EXTERN char Local_System_Name[15]; 537 538 /* ··· 554 GLOBAL_EXTERN atomic_t midCount; 555 556 /* Misc globals */ 557 - GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions 558 to be established on existing mount if we 559 have the uid/password or Kerberos credential 560 or equivalent for current user */ ··· 563 GLOBAL_EXTERN unsigned int lookupCacheEnabled; 564 GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 565 with more secure ntlmssp2 challenge/resp */ 566 - GLOBAL_EXTERN unsigned int ntlmv2_support; /* better optional password hash */ 567 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ 568 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ 569 GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ 570 GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
··· 88 }; 89 90 enum securityEnum { 91 + LANMAN = 0, /* Legacy LANMAN auth */ 92 + NTLM, /* Legacy NTLM012 auth with NTLM hash */ 93 NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ 94 RawNTLMSSP, /* NTLMSSP without SPNEGO */ 95 NTLMSSP, /* NTLMSSP via SPNEGO */ ··· 157 /* 16th byte of RFC1001 workstation name is always null */ 158 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; 159 __u32 sequence_number; /* needed for CIFS PDU signature */ 160 + char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; 161 }; 162 163 /* ··· 179 struct cifsSesInfo { 180 struct list_head cifsSessionList; 181 struct semaphore sesSem; 182 + #if 0 183 struct cifsUidInfo *uidInfo; /* pointer to user info */ 184 + #endif 185 struct TCP_Server_Info *server; /* pointer to server info */ 186 atomic_t inUse; /* # of mounts (tree connections) on this ses */ 187 enum statusEnum status; 188 + unsigned overrideSecFlg; /* if non-zero override global sec flags */ 189 __u16 ipc_tid; /* special tid for connection to IPC share */ 190 __u16 flags; 191 char *serverOS; /* name of operating system underlying server */ ··· 194 char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for 195 TCP names - will ipv6 and sctp addresses fit? */ 196 char userName[MAX_USERNAME_SIZE + 1]; 197 + char * domainName; 198 char * password; 199 }; 200 /* session flags */ ··· 209 struct list_head openFileList; 210 struct semaphore tconSem; 211 struct cifsSesInfo *ses; /* pointer to session associated with */ 212 + char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ 213 char *nativeFileSystem; 214 __u16 tid; /* The 2 byte tree id */ 215 __u16 Flags; /* optional support bits */ 216 enum statusEnum tidStatus; 217 + atomic_t useCount; /* how many explicit/implicit mounts to share */ 218 #ifdef CONFIG_CIFS_STATS 219 atomic_t num_smbs_sent; 220 atomic_t num_writes; ··· 254 spinlock_t stat_lock; 255 #endif /* CONFIG_CIFS_STATS */ 256 FILE_SYSTEM_DEVICE_INFO fsDevInfo; 257 + FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ 258 FILE_SYSTEM_UNIX_INFO fsUnixInfo; 259 unsigned retry:1; 260 unsigned nocase:1; ··· 305 atomic_t wrtPending; /* handle in use - defer close */ 306 struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 307 char * search_resume_name; /* BB removeme BB */ 308 struct cifs_search_info srch_inf; 309 }; 310 ··· 391 struct smb_hdr *resp_buf; /* response buffer */ 392 int midState; /* wish this were enum but can not pass to wait_event */ 393 __u8 command; /* smb command code */ 394 unsigned largeBuf:1; /* if valid response, is pointer to large buf */ 395 + unsigned multiRsp:1; /* multiple trans2 responses for one request */ 396 + unsigned multiEnd:1; /* both received */ 397 }; 398 399 struct oplock_q_entry { ··· 430 #define CIFS_LARGE_BUFFER 2 431 #define CIFS_IOVEC 4 /* array of response buffers */ 432 433 + /* Security Flags: indicate type of session setup needed */ 434 + #define CIFSSEC_MAY_SIGN 0x00001 435 + #define CIFSSEC_MAY_NTLM 0x00002 436 + #define CIFSSEC_MAY_NTLMV2 0x00004 437 + #define CIFSSEC_MAY_KRB5 0x00008 438 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 439 + #define CIFSSEC_MAY_LANMAN 0x00010 440 + #define CIFSSEC_MAY_PLNTXT 0x00020 441 + #endif /* weak passwords */ 442 + #define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ 443 444 + #define CIFSSEC_MUST_SIGN 0x01001 445 + /* note that only one of the following can be set so the 446 + result of setting MUST flags more than once will be to 447 + require use of the stronger protocol */ 448 + #define CIFSSEC_MUST_NTLM 0x02002 449 + #define CIFSSEC_MUST_NTLMV2 0x04004 450 + #define CIFSSEC_MUST_KRB5 0x08008 451 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 452 + #define CIFSSEC_MUST_LANMAN 0x10010 453 + #define CIFSSEC_MUST_PLNTXT 0x20020 454 + #define CIFSSEC_MASK 0x37037 /* current flags supported if weak */ 455 + #else 456 + #define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */ 457 + #endif /* WEAK_PW_HASH */ 458 + #define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ 459 + 460 + #define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 461 + #define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2 462 /* 463 ***************************************************************** 464 * All constants go here ··· 500 GLOBAL_EXTERN struct list_head GlobalOplock_Q; 501 502 GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */ 503 + GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q;/* DirNotify response queue */ 504 505 /* 506 * Global transaction id (XID) information 507 */ 508 GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */ 509 + GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ 510 GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ 511 + GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ 512 + /* on midQ entries */ 513 GLOBAL_EXTERN char Local_System_Name[15]; 514 515 /* ··· 531 GLOBAL_EXTERN atomic_t midCount; 532 533 /* Misc globals */ 534 + GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions 535 to be established on existing mount if we 536 have the uid/password or Kerberos credential 537 or equivalent for current user */ ··· 540 GLOBAL_EXTERN unsigned int lookupCacheEnabled; 541 GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 542 with more secure ntlmssp2 challenge/resp */ 543 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ 544 + GLOBAL_EXTERN unsigned int secFlags; 545 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ 546 GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ 547 GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
+84 -14
fs/cifs/cifspdu.h
··· 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library; if not, write to the Free Software 19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 #ifndef _CIFSPDU_H ··· 24 25 #include <net/sock.h> 26 27 #define CIFS_PROT 0 28 - #define BAD_PROT CIFS_PROT+1 29 30 /* SMB command codes */ 31 /* Some commands have minimal (wct=0,bcc=0), or uninteresting, responses ··· 116 /* 117 * Size of the session key (crypto key encrypted with the password 118 */ 119 - #define CIFS_SESSION_KEY_SIZE (24) 120 121 /* 122 * Maximum user name length ··· 406 unsigned char DialectsArray[1]; 407 } __attribute__((packed)) NEGOTIATE_REQ; 408 409 typedef struct negotiate_rsp { 410 struct smb_hdr hdr; /* wct = 17 */ 411 __le16 DialectIndex; ··· 538 /* unsigned char * NativeOS; */ 539 /* unsigned char * NativeLanMan; */ 540 /* unsigned char * PrimaryDomain; */ 541 - } __attribute__((packed)) resp; /* NTLM response format (with or without extended security */ 542 543 struct { /* request format */ 544 struct smb_hdr hdr; /* wct = 10 */ ··· 549 __le16 MaxMpxCount; 550 __le16 VcNumber; 551 __u32 SessionKey; 552 - __le16 PassswordLength; 553 - __u32 Reserved; 554 __le16 ByteCount; 555 unsigned char AccountPassword[1]; /* followed by */ 556 /* STRING AccountName */ ··· 571 /* unsigned char * PrimaryDomain; */ 572 } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response */ 573 } __attribute__((packed)) SESSION_SETUP_ANDX; 574 575 #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" 576 ··· 622 } __attribute__((packed)) TCONX_REQ; 623 624 typedef struct smb_com_tconx_rsp { 625 - struct smb_hdr hdr; /* wct = 3 *//* note that Win2000 has sent wct=7 in some cases on responses. Four unspecified words followed OptionalSupport */ 626 __u8 AndXCommand; 627 __u8 AndXReserved; 628 __le16 AndXOffset; ··· 1374 #define SMB_FILE_MAXIMUM_INFO 0x40d 1375 1376 /* Find File infolevels */ 1377 #define SMB_FIND_FILE_DIRECTORY_INFO 0x101 1378 #define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102 1379 #define SMB_FIND_FILE_NAMES_INFO 0x103 ··· 1898 typedef struct { 1899 __le32 DeviceType; 1900 __le32 DeviceCharacteristics; 1901 - } __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info, level 0x104 */ 1902 1903 typedef struct { 1904 __le32 Attributes; 1905 __le32 MaxPathNameComponentLength; 1906 __le32 FileSystemNameLen; 1907 - char FileSystemName[52]; /* do not really need to save this - so potentially get only subset of name */ 1908 } __attribute__((packed)) FILE_SYSTEM_ATTRIBUTE_INFO; 1909 1910 /******************************************************************************/ ··· 2001 2002 struct file_allocation_info { 2003 __le64 AllocationSize; /* Note old Samba srvr rounds this up too much */ 2004 - } __attribute__((packed)); /* size used on disk, level 0x103 for set, 0x105 for query */ 2005 2006 struct file_end_of_file_info { 2007 __le64 FileSize; /* offset to end of file */ ··· 2109 __le32 ExtFileAttributes; 2110 __le32 FileNameLength; 2111 char FileName[1]; 2112 - } __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */ 2113 2114 typedef struct { 2115 __le32 NextEntryOffset; ··· 2124 __le32 FileNameLength; 2125 __le32 EaSize; /* length of the xattrs */ 2126 char FileName[1]; 2127 - } __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */ 2128 2129 typedef struct { 2130 __le32 NextEntryOffset; ··· 2141 __le32 Reserved; 2142 __u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ 2143 char FileName[1]; 2144 - } __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */ 2145 2146 typedef struct { 2147 __le32 NextEntryOffset; ··· 2159 __u8 Reserved; 2160 __u8 ShortName[12]; 2161 char FileName[1]; 2162 - } __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ 2163 2164 2165 struct win_dev {
··· 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 #ifndef _CIFSPDU_H ··· 24 25 #include <net/sock.h> 26 27 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 28 + #define LANMAN_PROT 0 29 + #define CIFS_PROT 1 30 + #else 31 #define CIFS_PROT 0 32 + #endif 33 + #define POSIX_PROT CIFS_PROT+1 34 + #define BAD_PROT 0xFFFF 35 36 /* SMB command codes */ 37 /* Some commands have minimal (wct=0,bcc=0), or uninteresting, responses ··· 110 /* 111 * Size of the session key (crypto key encrypted with the password 112 */ 113 + #define CIFS_SESS_KEY_SIZE (24) 114 115 /* 116 * Maximum user name length ··· 400 unsigned char DialectsArray[1]; 401 } __attribute__((packed)) NEGOTIATE_REQ; 402 403 + /* Dialect index is 13 for LANMAN */ 404 + 405 + typedef struct lanman_neg_rsp { 406 + struct smb_hdr hdr; /* wct = 13 */ 407 + __le16 DialectIndex; 408 + __le16 SecurityMode; 409 + __le16 MaxBufSize; 410 + __le16 MaxMpxCount; 411 + __le16 MaxNumberVcs; 412 + __le16 RawMode; 413 + __le32 SessionKey; 414 + __le32 ServerTime; 415 + __le16 ServerTimeZone; 416 + __le16 EncryptionKeyLength; 417 + __le16 Reserved; 418 + __u16 ByteCount; 419 + unsigned char EncryptionKey[1]; 420 + } __attribute__((packed)) LANMAN_NEG_RSP; 421 + 422 + #define READ_RAW_ENABLE 1 423 + #define WRITE_RAW_ENABLE 2 424 + #define RAW_ENABLE (READ_RAW_ENABLE | WRITE_RAW_ENABLE) 425 + 426 typedef struct negotiate_rsp { 427 struct smb_hdr hdr; /* wct = 17 */ 428 __le16 DialectIndex; ··· 509 /* unsigned char * NativeOS; */ 510 /* unsigned char * NativeLanMan; */ 511 /* unsigned char * PrimaryDomain; */ 512 + } __attribute__((packed)) resp; /* NTLM response with or without extended sec*/ 513 514 struct { /* request format */ 515 struct smb_hdr hdr; /* wct = 10 */ ··· 520 __le16 MaxMpxCount; 521 __le16 VcNumber; 522 __u32 SessionKey; 523 + __le16 PasswordLength; 524 + __u32 Reserved; /* encrypt key len and offset */ 525 __le16 ByteCount; 526 unsigned char AccountPassword[1]; /* followed by */ 527 /* STRING AccountName */ ··· 542 /* unsigned char * PrimaryDomain; */ 543 } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response */ 544 } __attribute__((packed)) SESSION_SETUP_ANDX; 545 + 546 + /* format of NLTMv2 Response ie "case sensitive password" hash when NTLMv2 */ 547 + 548 + struct ntlmssp2_name { 549 + __le16 type; 550 + __le16 length; 551 + /* char name[length]; */ 552 + } __attribute__((packed)); 553 + 554 + struct ntlmv2_resp { 555 + char ntlmv2_hash[CIFS_ENCPWD_SIZE]; 556 + __le32 blob_signature; 557 + __u32 reserved; 558 + __le64 time; 559 + __u64 client_chal; /* random */ 560 + __u32 reserved2; 561 + struct ntlmssp2_name names[1]; 562 + /* array of name entries could follow ending in minimum 4 byte struct */ 563 + } __attribute__((packed)); 564 + 565 566 #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" 567 ··· 573 } __attribute__((packed)) TCONX_REQ; 574 575 typedef struct smb_com_tconx_rsp { 576 + struct smb_hdr hdr; /* wct = 3 note that Win2000 has sent wct = 7 577 + in some cases on responses. Four unspecified 578 + words followed OptionalSupport */ 579 __u8 AndXCommand; 580 __u8 AndXReserved; 581 __le16 AndXOffset; ··· 1323 #define SMB_FILE_MAXIMUM_INFO 0x40d 1324 1325 /* Find File infolevels */ 1326 + #define SMB_FIND_FILE_INFO_STANDARD 0x001 1327 + #define SMB_FIND_FILE_QUERY_EA_SIZE 0x002 1328 + #define SMB_FIND_FILE_QUERY_EAS_FROM_LIST 0x003 1329 #define SMB_FIND_FILE_DIRECTORY_INFO 0x101 1330 #define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102 1331 #define SMB_FIND_FILE_NAMES_INFO 0x103 ··· 1844 typedef struct { 1845 __le32 DeviceType; 1846 __le32 DeviceCharacteristics; 1847 + } __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info level 0x104 */ 1848 1849 typedef struct { 1850 __le32 Attributes; 1851 __le32 MaxPathNameComponentLength; 1852 __le32 FileSystemNameLen; 1853 + char FileSystemName[52]; /* do not have to save this - get subset? */ 1854 } __attribute__((packed)) FILE_SYSTEM_ATTRIBUTE_INFO; 1855 1856 /******************************************************************************/ ··· 1947 1948 struct file_allocation_info { 1949 __le64 AllocationSize; /* Note old Samba srvr rounds this up too much */ 1950 + } __attribute__((packed)); /* size used on disk, for level 0x103 for set, 1951 + 0x105 for query */ 1952 1953 struct file_end_of_file_info { 1954 __le64 FileSize; /* offset to end of file */ ··· 2054 __le32 ExtFileAttributes; 2055 __le32 FileNameLength; 2056 char FileName[1]; 2057 + } __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF resp data */ 2058 2059 typedef struct { 2060 __le32 NextEntryOffset; ··· 2069 __le32 FileNameLength; 2070 __le32 EaSize; /* length of the xattrs */ 2071 char FileName[1]; 2072 + } __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 rsp data */ 2073 2074 typedef struct { 2075 __le32 NextEntryOffset; ··· 2086 __le32 Reserved; 2087 __u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ 2088 char FileName[1]; 2089 + } __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */ 2090 2091 typedef struct { 2092 __le32 NextEntryOffset; ··· 2104 __u8 Reserved; 2105 __u8 ShortName[12]; 2106 char FileName[1]; 2107 + } __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FFrsp data */ 2108 + 2109 + typedef struct { 2110 + __u32 ResumeKey; 2111 + __le16 CreationDate; /* SMB Date */ 2112 + __le16 CreationTime; /* SMB Time */ 2113 + __le16 LastAccessDate; 2114 + __le16 LastAccessTime; 2115 + __le16 LastWriteDate; 2116 + __le16 LastWriteTime; 2117 + __le32 DataSize; /* File Size (EOF) */ 2118 + __le32 AllocationSize; 2119 + __le16 Attributes; /* verify not u32 */ 2120 + __u8 FileNameLength; 2121 + char FileName[1]; 2122 + } __attribute__((packed)) FIND_FILE_STANDARD_INFO; /* level 0x1 FF resp data */ 2123 2124 2125 struct win_dev {
+9 -5
fs/cifs/cifsproto.h
··· 64 extern void header_assemble(struct smb_hdr *, char /* command */ , 65 const struct cifsTconInfo *, int /* length of 66 fixed section (word count) in two byte units */); 67 - #ifdef CONFIG_CIFS_EXPERIMENTAL 68 extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 69 struct cifsSesInfo *ses, 70 void ** request_buf); 71 extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 72 - const int stage, int * pNTLMv2_flg, 73 const struct nls_table *nls_cp); 74 - #endif 75 extern __u16 GetNextMid(struct TCP_Server_Info *server); 76 extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 77 struct cifsTconInfo *); ··· 283 extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, 284 __u32 expected_sequence_number); 285 extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); 286 - extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *); 287 - extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * ); 288 extern int CIFSSMBCopy(int xid, 289 struct cifsTconInfo *source_tcon, 290 const char *fromName,
··· 64 extern void header_assemble(struct smb_hdr *, char /* command */ , 65 const struct cifsTconInfo *, int /* length of 66 fixed section (word count) in two byte units */); 67 extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 68 struct cifsSesInfo *ses, 69 void ** request_buf); 70 extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 71 + const int stage, 72 const struct nls_table *nls_cp); 73 extern __u16 GetNextMid(struct TCP_Server_Info *server); 74 extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 75 struct cifsTconInfo *); ··· 285 extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, 286 __u32 expected_sequence_number); 287 extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); 288 + extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, 289 + const struct nls_table *); 290 + extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * ); 291 + extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 292 + const struct nls_table *); 293 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 294 + extern void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key); 295 + #endif /* CIFS_WEAK_PW_HASH */ 296 extern int CIFSSMBCopy(int xid, 297 struct cifsTconInfo *source_tcon, 298 const char *fromName,
+208 -87
fs/cifs/cifssmb.c
··· 44 int index; 45 char *name; 46 } protocols[] = { 47 {CIFS_PROT, "\2NT LM 0.12"}, 48 - {CIFS_PROT, "\2POSIX 2"}, 49 {BAD_PROT, "\2"} 50 }; 51 #else ··· 56 int index; 57 char *name; 58 } protocols[] = { 59 {CIFS_PROT, "\2NT LM 0.12"}, 60 {BAD_PROT, "\2"} 61 }; 62 #endif 63 64 65 /* Mark as invalid, all open files on tree connections since they ··· 209 return rc; 210 } 211 212 - #ifdef CONFIG_CIFS_EXPERIMENTAL 213 int 214 small_smb_init_no_tc(const int smb_command, const int wct, 215 struct cifsSesInfo *ses, void **request_buf) ··· 234 235 return rc; 236 } 237 - #endif /* CONFIG_CIFS_EXPERIMENTAL */ 238 239 /* If the return code is zero, this function must fill in request_buf pointer */ 240 static int ··· 341 /* potential retries of smb operations it turns out we can determine */ 342 /* from the mid flags when the request buffer can be resent without */ 343 /* having to use a second distinct buffer for the response */ 344 - *response_buf = *request_buf; 345 346 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 347 wct /*wct */ ); ··· 393 NEGOTIATE_RSP *pSMBr; 394 int rc = 0; 395 int bytes_returned; 396 struct TCP_Server_Info * server; 397 u16 count; 398 399 if(ses->server) 400 server = ses->server; ··· 408 (void **) &pSMB, (void **) &pSMBr); 409 if (rc) 410 return rc; 411 pSMB->hdr.Mid = GetNextMid(server); 412 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 413 - if (extended_security) 414 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 415 - 416 - count = strlen(protocols[0].name) + 1; 417 - strncpy(pSMB->DialectsArray, protocols[0].name, 30); 418 - /* null guaranteed to be at end of source and target buffers anyway */ 419 - 420 pSMB->hdr.smb_buf_length += count; 421 pSMB->ByteCount = cpu_to_le16(count); 422 423 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 424 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 425 - if (rc == 0) { 426 - server->secMode = pSMBr->SecurityMode; 427 - if((server->secMode & SECMODE_USER) == 0) 428 - cFYI(1,("share mode security")); 429 - server->secType = NTLM; /* BB override default for 430 - NTLMv2 or kerberos v5 */ 431 - /* one byte - no need to convert this or EncryptionKeyLen 432 - from little endian */ 433 - server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); 434 - /* probably no need to store and check maxvcs */ 435 - server->maxBuf = 436 - min(le32_to_cpu(pSMBr->MaxBufferSize), 437 - (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 438 - server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); 439 - cFYI(0, ("Max buf = %d", ses->server->maxBuf)); 440 - GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); 441 - server->capabilities = le32_to_cpu(pSMBr->Capabilities); 442 - server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); 443 - /* BB with UTC do we ever need to be using srvr timezone? */ 444 - if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 445 - memcpy(server->cryptKey, pSMBr->u.EncryptionKey, 446 - CIFS_CRYPTO_KEY_SIZE); 447 - } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) 448 - && (pSMBr->EncryptionKeyLength == 0)) { 449 - /* decode security blob */ 450 - } else 451 - rc = -EIO; 452 453 - /* BB might be helpful to save off the domain of server here */ 454 455 - if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && 456 - (server->capabilities & CAP_EXTENDED_SECURITY)) { 457 - count = pSMBr->ByteCount; 458 - if (count < 16) 459 - rc = -EIO; 460 - else if (count == 16) { 461 - server->secType = RawNTLMSSP; 462 - if (server->socketUseCount.counter > 1) { 463 - if (memcmp 464 - (server->server_GUID, 465 - pSMBr->u.extended_response. 466 - GUID, 16) != 0) { 467 - cFYI(1, ("server UID changed")); 468 - memcpy(server-> 469 - server_GUID, 470 - pSMBr->u. 471 - extended_response. 472 - GUID, 16); 473 - } 474 - } else 475 - memcpy(server->server_GUID, 476 - pSMBr->u.extended_response. 477 - GUID, 16); 478 - } else { 479 - rc = decode_negTokenInit(pSMBr->u. 480 - extended_response. 481 - SecurityBlob, 482 - count - 16, 483 - &server->secType); 484 - if(rc == 1) { 485 - /* BB Need to fill struct for sessetup here */ 486 - rc = -EOPNOTSUPP; 487 - } else { 488 - rc = -EINVAL; 489 - } 490 - } 491 - } else 492 - server->capabilities &= ~CAP_EXTENDED_SECURITY; 493 - if(sign_CIFS_PDUs == FALSE) { 494 - if(server->secMode & SECMODE_SIGN_REQUIRED) 495 - cERROR(1, 496 - ("Server requires /proc/fs/cifs/PacketSigningEnabled")); 497 - server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 498 - } else if(sign_CIFS_PDUs == 1) { 499 - if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) 500 - server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 501 } 502 - 503 } 504 - 505 cifs_buf_release(pSMB); 506 return rc; 507 } 508 ··· 2360 } 2361 symlinkinfo[buflen] = 0; /* just in case so the caller 2362 does not go off the end of the buffer */ 2363 - cFYI(1,("readlink result - %s ",symlinkinfo)); 2364 } 2365 } 2366 qreparse_out:
··· 44 int index; 45 char *name; 46 } protocols[] = { 47 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 48 + {LANMAN_PROT, "\2LM1.2X002"}, 49 + #endif /* weak password hashing for legacy clients */ 50 {CIFS_PROT, "\2NT LM 0.12"}, 51 + {POSIX_PROT, "\2POSIX 2"}, 52 {BAD_PROT, "\2"} 53 }; 54 #else ··· 53 int index; 54 char *name; 55 } protocols[] = { 56 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 57 + {LANMAN_PROT, "\2LM1.2X002"}, 58 + #endif /* weak password hashing for legacy clients */ 59 {CIFS_PROT, "\2NT LM 0.12"}, 60 {BAD_PROT, "\2"} 61 }; 62 #endif 63 + 64 + /* define the number of elements in the cifs dialect array */ 65 + #ifdef CONFIG_CIFS_POSIX 66 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 67 + #define CIFS_NUM_PROT 3 68 + #else 69 + #define CIFS_NUM_PROT 2 70 + #endif /* CIFS_WEAK_PW_HASH */ 71 + #else /* not posix */ 72 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 73 + #define CIFS_NUM_PROT 2 74 + #else 75 + #define CIFS_NUM_PROT 1 76 + #endif /* CONFIG_CIFS_WEAK_PW_HASH */ 77 + #endif /* CIFS_POSIX */ 78 79 80 /* Mark as invalid, all open files on tree connections since they ··· 188 return rc; 189 } 190 191 int 192 small_smb_init_no_tc(const int smb_command, const int wct, 193 struct cifsSesInfo *ses, void **request_buf) ··· 214 215 return rc; 216 } 217 218 /* If the return code is zero, this function must fill in request_buf pointer */ 219 static int ··· 322 /* potential retries of smb operations it turns out we can determine */ 323 /* from the mid flags when the request buffer can be resent without */ 324 /* having to use a second distinct buffer for the response */ 325 + if(response_buf) 326 + *response_buf = *request_buf; 327 328 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 329 wct /*wct */ ); ··· 373 NEGOTIATE_RSP *pSMBr; 374 int rc = 0; 375 int bytes_returned; 376 + int i; 377 struct TCP_Server_Info * server; 378 u16 count; 379 + unsigned int secFlags; 380 381 if(ses->server) 382 server = ses->server; ··· 386 (void **) &pSMB, (void **) &pSMBr); 387 if (rc) 388 return rc; 389 + 390 + /* if any of auth flags (ie not sign or seal) are overriden use them */ 391 + if(ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) 392 + secFlags = ses->overrideSecFlg; 393 + else /* if override flags set only sign/seal OR them with global auth */ 394 + secFlags = extended_security | ses->overrideSecFlg; 395 + 396 + cFYI(1,("secFlags 0x%x",secFlags)); 397 + 398 pSMB->hdr.Mid = GetNextMid(server); 399 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 400 + if((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 401 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 402 + 403 + count = 0; 404 + for(i=0;i<CIFS_NUM_PROT;i++) { 405 + strncpy(pSMB->DialectsArray+count, protocols[i].name, 16); 406 + count += strlen(protocols[i].name) + 1; 407 + /* null at end of source and target buffers anyway */ 408 + } 409 pSMB->hdr.smb_buf_length += count; 410 pSMB->ByteCount = cpu_to_le16(count); 411 412 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 413 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 414 + if (rc != 0) 415 + goto neg_err_exit; 416 417 + cFYI(1,("Dialect: %d", pSMBr->DialectIndex)); 418 + /* Check wct = 1 error case */ 419 + if((pSMBr->hdr.WordCount < 13) || (pSMBr->DialectIndex == BAD_PROT)) { 420 + /* core returns wct = 1, but we do not ask for core - otherwise 421 + small wct just comes when dialect index is -1 indicating we 422 + could not negotiate a common dialect */ 423 + rc = -EOPNOTSUPP; 424 + goto neg_err_exit; 425 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 426 + } else if((pSMBr->hdr.WordCount == 13) 427 + && (pSMBr->DialectIndex == LANMAN_PROT)) { 428 + struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; 429 430 + if((secFlags & CIFSSEC_MAY_LANMAN) || 431 + (secFlags & CIFSSEC_MAY_PLNTXT)) 432 + server->secType = LANMAN; 433 + else { 434 + cERROR(1, ("mount failed weak security disabled" 435 + " in /proc/fs/cifs/SecurityFlags")); 436 + rc = -EOPNOTSUPP; 437 + goto neg_err_exit; 438 + } 439 + server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); 440 + server->maxReq = le16_to_cpu(rsp->MaxMpxCount); 441 + server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), 442 + (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 443 + GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); 444 + /* even though we do not use raw we might as well set this 445 + accurately, in case we ever find a need for it */ 446 + if((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { 447 + server->maxRw = 0xFF00; 448 + server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; 449 + } else { 450 + server->maxRw = 0;/* we do not need to use raw anyway */ 451 + server->capabilities = CAP_MPX_MODE; 452 } 453 + server->timeZone = le16_to_cpu(rsp->ServerTimeZone); 454 + 455 + /* BB get server time for time conversions and add 456 + code to use it and timezone since this is not UTC */ 457 + 458 + if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 459 + memcpy(server->cryptKey, rsp->EncryptionKey, 460 + CIFS_CRYPTO_KEY_SIZE); 461 + } else if (server->secMode & SECMODE_PW_ENCRYPT) { 462 + rc = -EIO; /* need cryptkey unless plain text */ 463 + goto neg_err_exit; 464 + } 465 + 466 + cFYI(1,("LANMAN negotiated")); 467 + /* we will not end up setting signing flags - as no signing 468 + was in LANMAN and server did not return the flags on */ 469 + goto signing_check; 470 + #else /* weak security disabled */ 471 + } else if(pSMBr->hdr.WordCount == 13) { 472 + cERROR(1,("mount failed, cifs module not built " 473 + "with CIFS_WEAK_PW_HASH support")); 474 + rc = -EOPNOTSUPP; 475 + #endif /* WEAK_PW_HASH */ 476 + goto neg_err_exit; 477 + } else if(pSMBr->hdr.WordCount != 17) { 478 + /* unknown wct */ 479 + rc = -EOPNOTSUPP; 480 + goto neg_err_exit; 481 } 482 + /* else wct == 17 NTLM */ 483 + server->secMode = pSMBr->SecurityMode; 484 + if((server->secMode & SECMODE_USER) == 0) 485 + cFYI(1,("share mode security")); 486 + 487 + if((server->secMode & SECMODE_PW_ENCRYPT) == 0) 488 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 489 + if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0) 490 + #endif /* CIFS_WEAK_PW_HASH */ 491 + cERROR(1,("Server requests plain text password" 492 + " but client support disabled")); 493 + 494 + if((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2) 495 + server->secType = NTLMv2; 496 + else if(secFlags & CIFSSEC_MAY_NTLM) 497 + server->secType = NTLM; 498 + else if(secFlags & CIFSSEC_MAY_NTLMV2) 499 + server->secType = NTLMv2; 500 + /* else krb5 ... any others ... */ 501 + 502 + /* one byte, so no need to convert this or EncryptionKeyLen from 503 + little endian */ 504 + server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); 505 + /* probably no need to store and check maxvcs */ 506 + server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), 507 + (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 508 + server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); 509 + cFYI(0, ("Max buf = %d", ses->server->maxBuf)); 510 + GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); 511 + server->capabilities = le32_to_cpu(pSMBr->Capabilities); 512 + server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); 513 + if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 514 + memcpy(server->cryptKey, pSMBr->u.EncryptionKey, 515 + CIFS_CRYPTO_KEY_SIZE); 516 + } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) 517 + && (pSMBr->EncryptionKeyLength == 0)) { 518 + /* decode security blob */ 519 + } else if (server->secMode & SECMODE_PW_ENCRYPT) { 520 + rc = -EIO; /* no crypt key only if plain text pwd */ 521 + goto neg_err_exit; 522 + } 523 + 524 + /* BB might be helpful to save off the domain of server here */ 525 + 526 + if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && 527 + (server->capabilities & CAP_EXTENDED_SECURITY)) { 528 + count = pSMBr->ByteCount; 529 + if (count < 16) 530 + rc = -EIO; 531 + else if (count == 16) { 532 + server->secType = RawNTLMSSP; 533 + if (server->socketUseCount.counter > 1) { 534 + if (memcmp(server->server_GUID, 535 + pSMBr->u.extended_response. 536 + GUID, 16) != 0) { 537 + cFYI(1, ("server UID changed")); 538 + memcpy(server->server_GUID, 539 + pSMBr->u.extended_response.GUID, 540 + 16); 541 + } 542 + } else 543 + memcpy(server->server_GUID, 544 + pSMBr->u.extended_response.GUID, 16); 545 + } else { 546 + rc = decode_negTokenInit(pSMBr->u.extended_response. 547 + SecurityBlob, 548 + count - 16, 549 + &server->secType); 550 + if(rc == 1) { 551 + /* BB Need to fill struct for sessetup here */ 552 + rc = -EOPNOTSUPP; 553 + } else { 554 + rc = -EINVAL; 555 + } 556 + } 557 + } else 558 + server->capabilities &= ~CAP_EXTENDED_SECURITY; 559 + 560 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 561 + signing_check: 562 + #endif 563 + if(sign_CIFS_PDUs == FALSE) { 564 + if(server->secMode & SECMODE_SIGN_REQUIRED) 565 + cERROR(1,("Server requires " 566 + "/proc/fs/cifs/PacketSigningEnabled to be on")); 567 + server->secMode &= 568 + ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 569 + } else if(sign_CIFS_PDUs == 1) { 570 + if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) 571 + server->secMode &= 572 + ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 573 + } else if(sign_CIFS_PDUs == 2) { 574 + if((server->secMode & 575 + (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { 576 + cERROR(1,("signing required but server lacks support")); 577 + } 578 + } 579 + neg_err_exit: 580 cifs_buf_release(pSMB); 581 + 582 + cFYI(1,("negprot rc %d",rc)); 583 return rc; 584 } 585 ··· 2239 } 2240 symlinkinfo[buflen] = 0; /* just in case so the caller 2241 does not go off the end of the buffer */ 2242 + cFYI(1,("readlink result - %s",symlinkinfo)); 2243 } 2244 } 2245 qreparse_out:
+110 -388
fs/cifs/connect.c
··· 49 50 static DECLARE_COMPLETION(cifsd_complete); 51 52 - extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, 53 - unsigned char *p24); 54 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 55 unsigned char *p24); 56 ··· 68 gid_t linux_gid; 69 mode_t file_mode; 70 mode_t dir_mode; 71 unsigned rw:1; 72 unsigned retry:1; 73 unsigned intr:1; ··· 82 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 83 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ 84 unsigned sfu_emul:1; 85 - unsigned krb5:1; 86 - unsigned ntlm:1; 87 - unsigned ntlmv2:1; 88 unsigned nullauth:1; /* attempt to authenticate with null user */ 89 - unsigned sign:1; 90 - unsigned seal:1; /* encrypt */ 91 unsigned nocase; /* request case insensitive filenames */ 92 unsigned nobrl; /* disable sending byte range locks to srv */ 93 unsigned int rsize; ··· 363 continue; 364 if (bigbuf == NULL) { 365 bigbuf = cifs_buf_get(); 366 - if(bigbuf == NULL) { 367 - cERROR(1,("No memory for large SMB response")); 368 msleep(3000); 369 /* retry will check if exiting */ 370 continue; 371 } 372 - } else if(isLargeBuf) { 373 - /* we are reusing a dirtry large buf, clear its start */ 374 memset(bigbuf, 0, sizeof (struct smb_hdr)); 375 } 376 377 if (smallbuf == NULL) { 378 smallbuf = cifs_small_buf_get(); 379 - if(smallbuf == NULL) { 380 - cERROR(1,("No memory for SMB response")); 381 msleep(1000); 382 /* retry will check if exiting */ 383 continue; ··· 397 kernel_recvmsg(csocket, &smb_msg, 398 &iov, 1, 4, 0 /* BB see socket.h flags */); 399 400 - if(server->tcpStatus == CifsExiting) { 401 break; 402 } else if (server->tcpStatus == CifsNeedReconnect) { 403 - cFYI(1,("Reconnect after server stopped responding")); 404 cifs_reconnect(server); 405 - cFYI(1,("call to reconnect done")); 406 csocket = server->ssocket; 407 continue; 408 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { ··· 411 tcpStatus CifsNeedReconnect if server hung */ 412 continue; 413 } else if (length <= 0) { 414 - if(server->tcpStatus == CifsNew) { 415 - cFYI(1,("tcp session abend after SMBnegprot")); 416 /* some servers kill the TCP session rather than 417 returning an SMB negprot error, in which 418 case reconnecting here is not going to help, 419 and so simply return error to mount */ 420 break; 421 } 422 - if(length == -EINTR) { 423 cFYI(1,("cifsd thread killed")); 424 break; 425 } ··· 579 /* merge response - fix up 1st*/ 580 if(coalesce_t2(smb_buffer, 581 mid_entry->resp_buf)) { 582 break; 583 } else { 584 /* all parts received */ 585 goto multi_t2_fnd; 586 } 587 } else { ··· 628 wake_up_process(task_to_wake); 629 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE) 630 && (isMultiRsp == FALSE)) { 631 - cERROR(1, ("No task to wake, unknown frame rcvd!")); 632 cifs_dump_mem("Received Data is: ",(char *)smb_buffer, 633 sizeof(struct smb_hdr)); 634 } 635 } /* end while !EXITING */ 636 ··· 785 786 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ 787 vol->rw = TRUE; 788 - vol->ntlm = TRUE; 789 /* default is always to request posix paths. */ 790 vol->posix_paths = 1; 791 ··· 915 cERROR(1,("no security value specified")); 916 continue; 917 } else if (strnicmp(value, "krb5i", 5) == 0) { 918 - vol->sign = 1; 919 - vol->krb5 = 1; 920 } else if (strnicmp(value, "krb5p", 5) == 0) { 921 - /* vol->seal = 1; 922 - vol->krb5 = 1; */ 923 cERROR(1,("Krb5 cifs privacy not supported")); 924 return 1; 925 } else if (strnicmp(value, "krb5", 4) == 0) { 926 - vol->krb5 = 1; 927 } else if (strnicmp(value, "ntlmv2i", 7) == 0) { 928 - vol->ntlmv2 = 1; 929 - vol->sign = 1; 930 } else if (strnicmp(value, "ntlmv2", 6) == 0) { 931 - vol->ntlmv2 = 1; 932 } else if (strnicmp(value, "ntlmi", 5) == 0) { 933 - vol->ntlm = 1; 934 - vol->sign = 1; 935 } else if (strnicmp(value, "ntlm", 4) == 0) { 936 /* ntlm is default so can be turned off too */ 937 - vol->ntlm = 1; 938 } else if (strnicmp(value, "nontlm", 6) == 0) { 939 - vol->ntlm = 0; 940 } else if (strnicmp(value, "none", 4) == 0) { 941 - vol->nullauth = 1; 942 } else { 943 cERROR(1,("bad security option: %s", value)); 944 return 1; ··· 981 } 982 /* BB are there cases in which a comma can be valid in 983 a domain name and need special handling? */ 984 - if (strnlen(value, 65) < 65) { 985 vol->domainname = value; 986 cFYI(1, ("Domain name set")); 987 } else { ··· 1173 vol->no_psx_acl = 0; 1174 } else if (strnicmp(data, "noacl",5) == 0) { 1175 vol->no_psx_acl = 1; 1176 } else if (strnicmp(data, "direct",6) == 0) { 1177 vol->direct_io = 1; 1178 } else if (strnicmp(data, "forcedirectio",13) == 0) { ··· 1771 if (volume_info.username) 1772 strncpy(pSesInfo->userName, 1773 volume_info.username,MAX_USERNAME_SIZE); 1774 - if (volume_info.domainname) 1775 - strncpy(pSesInfo->domainName, 1776 - volume_info.domainname,MAX_USERNAME_SIZE); 1777 pSesInfo->linux_uid = volume_info.linux_uid; 1778 down(&pSesInfo->sesSem); 1779 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); 1780 up(&pSesInfo->sesSem); 1781 if(!rc) ··· 1996 1997 static int 1998 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, 1999 - char session_key[CIFS_SESSION_KEY_SIZE], 2000 const struct nls_table *nls_codepage) 2001 { 2002 struct smb_hdr *smb_buffer; ··· 2054 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 2055 2056 pSMB->req_no_secext.CaseInsensitivePasswordLength = 2057 - cpu_to_le16(CIFS_SESSION_KEY_SIZE); 2058 2059 pSMB->req_no_secext.CaseSensitivePasswordLength = 2060 - cpu_to_le16(CIFS_SESSION_KEY_SIZE); 2061 bcc_ptr = pByteArea(smb_buffer); 2062 - memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE); 2063 - bcc_ptr += CIFS_SESSION_KEY_SIZE; 2064 - memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE); 2065 - bcc_ptr += CIFS_SESSION_KEY_SIZE; 2066 2067 if (ses->capabilities & CAP_UNICODE) { 2068 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */ ··· 2070 bcc_ptr++; 2071 } 2072 if(user == NULL) 2073 - bytes_returned = 0; /* skill null user */ 2074 else 2075 bytes_returned = 2076 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, ··· 2178 if (remaining_words > 0) { 2179 len = UniStrnlen((wchar_t *)bcc_ptr, 2180 remaining_words-1); 2181 - if(ses->serverNOS) 2182 - kfree(ses->serverNOS); 2183 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL); 2184 if(ses->serverNOS == NULL) 2185 goto sesssetup_nomem; ··· 2218 /* if these kcallocs fail not much we 2219 can do, but better to not fail the 2220 sesssetup itself */ 2221 - if(ses->serverDomain) 2222 - kfree(ses->serverDomain); 2223 ses->serverDomain = 2224 kzalloc(2, GFP_KERNEL); 2225 - if(ses->serverNOS) 2226 - kfree(ses->serverNOS); 2227 ses->serverNOS = 2228 kzalloc(2, GFP_KERNEL); 2229 } ··· 2230 if (((long) bcc_ptr + len) - (long) 2231 pByteArea(smb_buffer_response) 2232 <= BCC(smb_buffer_response)) { 2233 - if(ses->serverOS) 2234 - kfree(ses->serverOS); 2235 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 2236 if(ses->serverOS == NULL) 2237 goto sesssetup_nomem; ··· 2241 bcc_ptr++; 2242 2243 len = strnlen(bcc_ptr, 1024); 2244 - if(ses->serverNOS) 2245 - kfree(ses->serverNOS); 2246 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); 2247 if(ses->serverNOS == NULL) 2248 goto sesssetup_nomem; ··· 2278 sesssetup_nomem: /* do not return an error on nomem for the info strings, 2279 since that could make reconnection harder, and 2280 reconnection might be needed to free memory */ 2281 - if (smb_buffer) 2282 - cifs_buf_release(smb_buffer); 2283 - 2284 - return rc; 2285 - } 2286 - 2287 - static int 2288 - CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, 2289 - char *SecurityBlob,int SecurityBlobLength, 2290 - const struct nls_table *nls_codepage) 2291 - { 2292 - struct smb_hdr *smb_buffer; 2293 - struct smb_hdr *smb_buffer_response; 2294 - SESSION_SETUP_ANDX *pSMB; 2295 - SESSION_SETUP_ANDX *pSMBr; 2296 - char *bcc_ptr; 2297 - char *user; 2298 - char *domain; 2299 - int rc = 0; 2300 - int remaining_words = 0; 2301 - int bytes_returned = 0; 2302 - int len; 2303 - __u32 capabilities; 2304 - __u16 count; 2305 - 2306 - cFYI(1, ("In spnego sesssetup ")); 2307 - if(ses == NULL) 2308 - return -EINVAL; 2309 - user = ses->userName; 2310 - domain = ses->domainName; 2311 - 2312 - smb_buffer = cifs_buf_get(); 2313 - if (smb_buffer == NULL) { 2314 - return -ENOMEM; 2315 - } 2316 - smb_buffer_response = smb_buffer; 2317 - pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer; 2318 - 2319 - /* send SMBsessionSetup here */ 2320 - header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 2321 - NULL /* no tCon exists yet */ , 12 /* wct */ ); 2322 - 2323 - smb_buffer->Mid = GetNextMid(ses->server); 2324 - pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2325 - pSMB->req.AndXCommand = 0xFF; 2326 - if(ses->server->maxBuf > 64*1024) 2327 - ses->server->maxBuf = (64*1023); 2328 - pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2329 - pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2330 - 2331 - if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 2332 - smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 2333 - 2334 - capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 2335 - CAP_EXTENDED_SECURITY; 2336 - if (ses->capabilities & CAP_UNICODE) { 2337 - smb_buffer->Flags2 |= SMBFLG2_UNICODE; 2338 - capabilities |= CAP_UNICODE; 2339 - } 2340 - if (ses->capabilities & CAP_STATUS32) { 2341 - smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS; 2342 - capabilities |= CAP_STATUS32; 2343 - } 2344 - if (ses->capabilities & CAP_DFS) { 2345 - smb_buffer->Flags2 |= SMBFLG2_DFS; 2346 - capabilities |= CAP_DFS; 2347 - } 2348 - pSMB->req.Capabilities = cpu_to_le32(capabilities); 2349 - 2350 - pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength); 2351 - bcc_ptr = pByteArea(smb_buffer); 2352 - memcpy(bcc_ptr, SecurityBlob, SecurityBlobLength); 2353 - bcc_ptr += SecurityBlobLength; 2354 - 2355 - if (ses->capabilities & CAP_UNICODE) { 2356 - if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode strings */ 2357 - *bcc_ptr = 0; 2358 - bcc_ptr++; 2359 - } 2360 - bytes_returned = 2361 - cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage); 2362 - bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */ 2363 - bcc_ptr += 2; /* trailing null */ 2364 - if (domain == NULL) 2365 - bytes_returned = 2366 - cifs_strtoUCS((__le16 *) bcc_ptr, 2367 - "CIFS_LINUX_DOM", 32, nls_codepage); 2368 - else 2369 - bytes_returned = 2370 - cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, 2371 - nls_codepage); 2372 - bcc_ptr += 2 * bytes_returned; 2373 - bcc_ptr += 2; 2374 - bytes_returned = 2375 - cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ", 2376 - 32, nls_codepage); 2377 - bcc_ptr += 2 * bytes_returned; 2378 - bytes_returned = 2379 - cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32, 2380 - nls_codepage); 2381 - bcc_ptr += 2 * bytes_returned; 2382 - bcc_ptr += 2; 2383 - bytes_returned = 2384 - cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 2385 - 64, nls_codepage); 2386 - bcc_ptr += 2 * bytes_returned; 2387 - bcc_ptr += 2; 2388 - } else { 2389 - strncpy(bcc_ptr, user, 200); 2390 - bcc_ptr += strnlen(user, 200); 2391 - *bcc_ptr = 0; 2392 - bcc_ptr++; 2393 - if (domain == NULL) { 2394 - strcpy(bcc_ptr, "CIFS_LINUX_DOM"); 2395 - bcc_ptr += strlen("CIFS_LINUX_DOM") + 1; 2396 - } else { 2397 - strncpy(bcc_ptr, domain, 64); 2398 - bcc_ptr += strnlen(domain, 64); 2399 - *bcc_ptr = 0; 2400 - bcc_ptr++; 2401 - } 2402 - strcpy(bcc_ptr, "Linux version "); 2403 - bcc_ptr += strlen("Linux version "); 2404 - strcpy(bcc_ptr, system_utsname.release); 2405 - bcc_ptr += strlen(system_utsname.release) + 1; 2406 - strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); 2407 - bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; 2408 - } 2409 - count = (long) bcc_ptr - (long) pByteArea(smb_buffer); 2410 - smb_buffer->smb_buf_length += count; 2411 - pSMB->req.ByteCount = cpu_to_le16(count); 2412 - 2413 - rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 2414 - &bytes_returned, 1); 2415 - if (rc) { 2416 - /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */ 2417 - } else if ((smb_buffer_response->WordCount == 3) 2418 - || (smb_buffer_response->WordCount == 4)) { 2419 - __u16 action = le16_to_cpu(pSMBr->resp.Action); 2420 - __u16 blob_len = 2421 - le16_to_cpu(pSMBr->resp.SecurityBlobLength); 2422 - if (action & GUEST_LOGIN) 2423 - cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */ 2424 - if (ses) { 2425 - ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */ 2426 - cFYI(1, ("UID = %d ", ses->Suid)); 2427 - bcc_ptr = pByteArea(smb_buffer_response); /* response can have either 3 or 4 word count - Samba sends 3 */ 2428 - 2429 - /* BB Fix below to make endian neutral !! */ 2430 - 2431 - if ((pSMBr->resp.hdr.WordCount == 3) 2432 - || ((pSMBr->resp.hdr.WordCount == 4) 2433 - && (blob_len < 2434 - pSMBr->resp.ByteCount))) { 2435 - if (pSMBr->resp.hdr.WordCount == 4) { 2436 - bcc_ptr += 2437 - blob_len; 2438 - cFYI(1, 2439 - ("Security Blob Length %d ", 2440 - blob_len)); 2441 - } 2442 - 2443 - if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 2444 - if ((long) (bcc_ptr) % 2) { 2445 - remaining_words = 2446 - (BCC(smb_buffer_response) 2447 - - 1) / 2; 2448 - bcc_ptr++; /* Unicode strings must be word aligned */ 2449 - } else { 2450 - remaining_words = 2451 - BCC 2452 - (smb_buffer_response) / 2; 2453 - } 2454 - len = 2455 - UniStrnlen((wchar_t *) bcc_ptr, 2456 - remaining_words - 1); 2457 - /* We look for obvious messed up bcc or strings in response so we do not go off 2458 - the end since (at least) WIN2K and Windows XP have a major bug in not null 2459 - terminating last Unicode string in response */ 2460 - if(ses->serverOS) 2461 - kfree(ses->serverOS); 2462 - ses->serverOS = 2463 - kzalloc(2 * (len + 1), GFP_KERNEL); 2464 - cifs_strfromUCS_le(ses->serverOS, 2465 - (__le16 *) 2466 - bcc_ptr, len, 2467 - nls_codepage); 2468 - bcc_ptr += 2 * (len + 1); 2469 - remaining_words -= len + 1; 2470 - ses->serverOS[2 * len] = 0; 2471 - ses->serverOS[1 + (2 * len)] = 0; 2472 - if (remaining_words > 0) { 2473 - len = UniStrnlen((wchar_t *)bcc_ptr, 2474 - remaining_words 2475 - - 1); 2476 - if(ses->serverNOS) 2477 - kfree(ses->serverNOS); 2478 - ses->serverNOS = 2479 - kzalloc(2 * (len + 1), 2480 - GFP_KERNEL); 2481 - cifs_strfromUCS_le(ses->serverNOS, 2482 - (__le16 *)bcc_ptr, 2483 - len, 2484 - nls_codepage); 2485 - bcc_ptr += 2 * (len + 1); 2486 - ses->serverNOS[2 * len] = 0; 2487 - ses->serverNOS[1 + (2 * len)] = 0; 2488 - remaining_words -= len + 1; 2489 - if (remaining_words > 0) { 2490 - len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2491 - /* last string not null terminated (e.g.Windows XP/2000) */ 2492 - if(ses->serverDomain) 2493 - kfree(ses->serverDomain); 2494 - ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL); 2495 - cifs_strfromUCS_le(ses->serverDomain, 2496 - (__le16 *)bcc_ptr, 2497 - len, nls_codepage); 2498 - bcc_ptr += 2*(len+1); 2499 - ses->serverDomain[2*len] = 0; 2500 - ses->serverDomain[1+(2*len)] = 0; 2501 - } /* else no more room so create dummy domain string */ 2502 - else { 2503 - if(ses->serverDomain) 2504 - kfree(ses->serverDomain); 2505 - ses->serverDomain = 2506 - kzalloc(2,GFP_KERNEL); 2507 - } 2508 - } else {/* no room use dummy domain&NOS */ 2509 - if(ses->serverDomain) 2510 - kfree(ses->serverDomain); 2511 - ses->serverDomain = kzalloc(2, GFP_KERNEL); 2512 - if(ses->serverNOS) 2513 - kfree(ses->serverNOS); 2514 - ses->serverNOS = kzalloc(2, GFP_KERNEL); 2515 - } 2516 - } else { /* ASCII */ 2517 - 2518 - len = strnlen(bcc_ptr, 1024); 2519 - if (((long) bcc_ptr + len) - (long) 2520 - pByteArea(smb_buffer_response) 2521 - <= BCC(smb_buffer_response)) { 2522 - if(ses->serverOS) 2523 - kfree(ses->serverOS); 2524 - ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 2525 - strncpy(ses->serverOS, bcc_ptr, len); 2526 - 2527 - bcc_ptr += len; 2528 - bcc_ptr[0] = 0; /* null terminate the string */ 2529 - bcc_ptr++; 2530 - 2531 - len = strnlen(bcc_ptr, 1024); 2532 - if(ses->serverNOS) 2533 - kfree(ses->serverNOS); 2534 - ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); 2535 - strncpy(ses->serverNOS, bcc_ptr, len); 2536 - bcc_ptr += len; 2537 - bcc_ptr[0] = 0; 2538 - bcc_ptr++; 2539 - 2540 - len = strnlen(bcc_ptr, 1024); 2541 - if(ses->serverDomain) 2542 - kfree(ses->serverDomain); 2543 - ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); 2544 - strncpy(ses->serverDomain, bcc_ptr, len); 2545 - bcc_ptr += len; 2546 - bcc_ptr[0] = 0; 2547 - bcc_ptr++; 2548 - } else 2549 - cFYI(1, 2550 - ("Variable field of length %d extends beyond end of smb ", 2551 - len)); 2552 - } 2553 - } else { 2554 - cERROR(1, 2555 - (" Security Blob Length extends beyond end of SMB")); 2556 - } 2557 - } else { 2558 - cERROR(1, ("No session structure passed in.")); 2559 - } 2560 - } else { 2561 - cERROR(1, 2562 - (" Invalid Word count %d: ", 2563 - smb_buffer_response->WordCount)); 2564 - rc = -EIO; 2565 - } 2566 - 2567 if (smb_buffer) 2568 cifs_buf_release(smb_buffer); 2569 ··· 2360 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; 2361 if(sign_CIFS_PDUs) 2362 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; 2363 - if(ntlmv2_support) 2364 - negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2; 2365 /* setup pointers to domain name and workstation name */ 2366 bcc_ptr += SecurityBlobLength; 2367 ··· 2508 bcc_ptr, 2509 remaining_words 2510 - 1); 2511 - if(ses->serverNOS) 2512 - kfree(ses->serverNOS); 2513 ses->serverNOS = 2514 kzalloc(2 * (len + 1), 2515 GFP_KERNEL); ··· 2526 if (remaining_words > 0) { 2527 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2528 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2529 - if(ses->serverDomain) 2530 - kfree(ses->serverDomain); 2531 ses->serverDomain = 2532 kzalloc(2 * 2533 (len + ··· 2545 = 0; 2546 } /* else no more room so create dummy domain string */ 2547 else { 2548 - if(ses->serverDomain) 2549 - kfree(ses->serverDomain); 2550 ses->serverDomain = 2551 kzalloc(2, 2552 GFP_KERNEL); 2553 } 2554 } else { /* no room so create dummy domain and NOS string */ 2555 - if(ses->serverDomain); 2556 - kfree(ses->serverDomain); 2557 ses->serverDomain = 2558 kzalloc(2, GFP_KERNEL); 2559 - if(ses->serverNOS) 2560 - kfree(ses->serverNOS); 2561 ses->serverNOS = 2562 kzalloc(2, GFP_KERNEL); 2563 } ··· 2576 bcc_ptr++; 2577 2578 len = strnlen(bcc_ptr, 1024); 2579 - if(ses->serverNOS) 2580 - kfree(ses->serverNOS); 2581 ses->serverNOS = 2582 kzalloc(len + 1, 2583 GFP_KERNEL); ··· 2586 bcc_ptr++; 2587 2588 len = strnlen(bcc_ptr, 1024); 2589 - if(ses->serverDomain) 2590 - kfree(ses->serverDomain); 2591 ses->serverDomain = 2592 kzalloc(len + 1, 2593 GFP_KERNEL); ··· 2712 SecurityBlob->LmChallengeResponse.Buffer = 0; 2713 2714 SecurityBlob->NtChallengeResponse.Length = 2715 - cpu_to_le16(CIFS_SESSION_KEY_SIZE); 2716 SecurityBlob->NtChallengeResponse.MaximumLength = 2717 - cpu_to_le16(CIFS_SESSION_KEY_SIZE); 2718 - memcpy(bcc_ptr, ntlm_session_key, CIFS_SESSION_KEY_SIZE); 2719 SecurityBlob->NtChallengeResponse.Buffer = 2720 cpu_to_le32(SecurityBlobLength); 2721 - SecurityBlobLength += CIFS_SESSION_KEY_SIZE; 2722 - bcc_ptr += CIFS_SESSION_KEY_SIZE; 2723 2724 if (ses->capabilities & CAP_UNICODE) { 2725 if (domain == NULL) { ··· 2908 bcc_ptr, 2909 remaining_words 2910 - 1); 2911 - if(ses->serverNOS) 2912 - kfree(ses->serverNOS); 2913 ses->serverNOS = 2914 kzalloc(2 * (len + 1), 2915 GFP_KERNEL); ··· 2961 if(ses->serverDomain) 2962 kfree(ses->serverDomain); 2963 ses->serverDomain = kzalloc(2, GFP_KERNEL); 2964 - if(ses->serverNOS) 2965 - kfree(ses->serverNOS); 2966 ses->serverNOS = kzalloc(2, GFP_KERNEL); 2967 } 2968 } else { /* ASCII */ ··· 2979 bcc_ptr++; 2980 2981 len = strnlen(bcc_ptr, 1024); 2982 - if(ses->serverNOS) 2983 - kfree(ses->serverNOS); 2984 ses->serverNOS = kzalloc(len+1,GFP_KERNEL); 2985 strncpy(ses->serverNOS, bcc_ptr, len); 2986 bcc_ptr += len; ··· 3055 bcc_ptr = &pSMB->Password[0]; 3056 if((ses->server->secMode) & SECMODE_USER) { 3057 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 3058 bcc_ptr++; /* skip password */ 3059 } else { 3060 - pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE); 3061 /* BB FIXME add code to fail this if NTLMv2 or Kerberos 3062 specified as required (when that support is added to 3063 the vfs in the future) as only NTLM or the much 3064 - weaker LANMAN (which we do not send) is accepted 3065 by Samba (not sure whether other servers allow 3066 NTLMv2 password here) */ 3067 SMBNTencrypt(ses->password, 3068 ses->server->cryptKey, 3069 bcc_ptr); 3070 3071 - bcc_ptr += CIFS_SESSION_KEY_SIZE; 3072 - *bcc_ptr = 0; 3073 - bcc_ptr++; /* align */ 3074 } 3075 3076 if(ses->server->secMode & ··· 3155 } 3156 /* else do not bother copying these informational fields */ 3157 } 3158 - tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3159 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags)); 3160 } else if ((rc == 0) && tcon == NULL) { 3161 /* all we need to save for IPC$ connection */ ··· 3223 struct nls_table * nls_info) 3224 { 3225 int rc = 0; 3226 - char ntlm_session_key[CIFS_SESSION_KEY_SIZE]; 3227 int ntlmv2_flag = FALSE; 3228 int first_time = 0; 3229 ··· 3255 pSesInfo->server->secMode, 3256 pSesInfo->server->capabilities, 3257 pSesInfo->server->timeZone)); 3258 - #ifdef CONFIG_CIFS_EXPERIMENTAL 3259 - if(experimEnabled > 1) 3260 - rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */, 3261 - &ntlmv2_flag, nls_info); 3262 - else 3263 - #endif 3264 - if (extended_security 3265 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3266 && (pSesInfo->server->secType == NTLMSSP)) { 3267 - cFYI(1, ("New style sesssetup")); 3268 - rc = CIFSSpnegoSessSetup(xid, pSesInfo, 3269 - NULL /* security blob */, 3270 - 0 /* blob length */, 3271 - nls_info); 3272 } else if (extended_security 3273 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3274 && (pSesInfo->server->secType == RawNTLMSSP)) {
··· 49 50 static DECLARE_COMPLETION(cifsd_complete); 51 52 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 53 unsigned char *p24); 54 ··· 70 gid_t linux_gid; 71 mode_t file_mode; 72 mode_t dir_mode; 73 + unsigned secFlg; 74 unsigned rw:1; 75 unsigned retry:1; 76 unsigned intr:1; ··· 83 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 84 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ 85 unsigned sfu_emul:1; 86 unsigned nullauth:1; /* attempt to authenticate with null user */ 87 unsigned nocase; /* request case insensitive filenames */ 88 unsigned nobrl; /* disable sending byte range locks to srv */ 89 unsigned int rsize; ··· 369 continue; 370 if (bigbuf == NULL) { 371 bigbuf = cifs_buf_get(); 372 + if (!bigbuf) { 373 + cERROR(1, ("No memory for large SMB response")); 374 msleep(3000); 375 /* retry will check if exiting */ 376 continue; 377 } 378 + } else if (isLargeBuf) { 379 + /* we are reusing a dirty large buf, clear its start */ 380 memset(bigbuf, 0, sizeof (struct smb_hdr)); 381 } 382 383 if (smallbuf == NULL) { 384 smallbuf = cifs_small_buf_get(); 385 + if (!smallbuf) { 386 + cERROR(1, ("No memory for SMB response")); 387 msleep(1000); 388 /* retry will check if exiting */ 389 continue; ··· 403 kernel_recvmsg(csocket, &smb_msg, 404 &iov, 1, 4, 0 /* BB see socket.h flags */); 405 406 + if (server->tcpStatus == CifsExiting) { 407 break; 408 } else if (server->tcpStatus == CifsNeedReconnect) { 409 + cFYI(1, ("Reconnect after server stopped responding")); 410 cifs_reconnect(server); 411 + cFYI(1, ("call to reconnect done")); 412 csocket = server->ssocket; 413 continue; 414 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { ··· 417 tcpStatus CifsNeedReconnect if server hung */ 418 continue; 419 } else if (length <= 0) { 420 + if (server->tcpStatus == CifsNew) { 421 + cFYI(1, ("tcp session abend after SMBnegprot")); 422 /* some servers kill the TCP session rather than 423 returning an SMB negprot error, in which 424 case reconnecting here is not going to help, 425 and so simply return error to mount */ 426 break; 427 } 428 + if (!try_to_freeze() && (length == -EINTR)) { 429 cFYI(1,("cifsd thread killed")); 430 break; 431 } ··· 585 /* merge response - fix up 1st*/ 586 if(coalesce_t2(smb_buffer, 587 mid_entry->resp_buf)) { 588 + mid_entry->multiRsp = 1; 589 break; 590 } else { 591 /* all parts received */ 592 + mid_entry->multiEnd = 1; 593 goto multi_t2_fnd; 594 } 595 } else { ··· 632 wake_up_process(task_to_wake); 633 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE) 634 && (isMultiRsp == FALSE)) { 635 + cERROR(1, ("No task to wake, unknown frame rcvd! NumMids %d", midCount.counter)); 636 cifs_dump_mem("Received Data is: ",(char *)smb_buffer, 637 sizeof(struct smb_hdr)); 638 + #ifdef CONFIG_CIFS_DEBUG2 639 + cifs_dump_detail(smb_buffer); 640 + cifs_dump_mids(server); 641 + #endif /* CIFS_DEBUG2 */ 642 + 643 } 644 } /* end while !EXITING */ 645 ··· 784 785 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ 786 vol->rw = TRUE; 787 /* default is always to request posix paths. */ 788 vol->posix_paths = 1; 789 ··· 915 cERROR(1,("no security value specified")); 916 continue; 917 } else if (strnicmp(value, "krb5i", 5) == 0) { 918 + vol->secFlg |= CIFSSEC_MAY_KRB5 | 919 + CIFSSEC_MUST_SIGN; 920 } else if (strnicmp(value, "krb5p", 5) == 0) { 921 + /* vol->secFlg |= CIFSSEC_MUST_SEAL | 922 + CIFSSEC_MAY_KRB5; */ 923 cERROR(1,("Krb5 cifs privacy not supported")); 924 return 1; 925 } else if (strnicmp(value, "krb5", 4) == 0) { 926 + vol->secFlg |= CIFSSEC_MAY_KRB5; 927 } else if (strnicmp(value, "ntlmv2i", 7) == 0) { 928 + vol->secFlg |= CIFSSEC_MAY_NTLMV2 | 929 + CIFSSEC_MUST_SIGN; 930 } else if (strnicmp(value, "ntlmv2", 6) == 0) { 931 + vol->secFlg |= CIFSSEC_MAY_NTLMV2; 932 } else if (strnicmp(value, "ntlmi", 5) == 0) { 933 + vol->secFlg |= CIFSSEC_MAY_NTLM | 934 + CIFSSEC_MUST_SIGN; 935 } else if (strnicmp(value, "ntlm", 4) == 0) { 936 /* ntlm is default so can be turned off too */ 937 + vol->secFlg |= CIFSSEC_MAY_NTLM; 938 } else if (strnicmp(value, "nontlm", 6) == 0) { 939 + /* BB is there a better way to do this? */ 940 + vol->secFlg |= CIFSSEC_MAY_NTLMV2; 941 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 942 + } else if (strnicmp(value, "lanman", 6) == 0) { 943 + vol->secFlg |= CIFSSEC_MAY_LANMAN; 944 + #endif 945 } else if (strnicmp(value, "none", 4) == 0) { 946 + vol->nullauth = 1; 947 } else { 948 cERROR(1,("bad security option: %s", value)); 949 return 1; ··· 976 } 977 /* BB are there cases in which a comma can be valid in 978 a domain name and need special handling? */ 979 + if (strnlen(value, 256) < 256) { 980 vol->domainname = value; 981 cFYI(1, ("Domain name set")); 982 } else { ··· 1168 vol->no_psx_acl = 0; 1169 } else if (strnicmp(data, "noacl",5) == 0) { 1170 vol->no_psx_acl = 1; 1171 + } else if (strnicmp(data, "sign",4) == 0) { 1172 + vol->secFlg |= CIFSSEC_MUST_SIGN; 1173 + /* } else if (strnicmp(data, "seal",4) == 0) { 1174 + vol->secFlg |= CIFSSEC_MUST_SEAL; */ 1175 } else if (strnicmp(data, "direct",6) == 0) { 1176 vol->direct_io = 1; 1177 } else if (strnicmp(data, "forcedirectio",13) == 0) { ··· 1762 if (volume_info.username) 1763 strncpy(pSesInfo->userName, 1764 volume_info.username,MAX_USERNAME_SIZE); 1765 + if (volume_info.domainname) { 1766 + int len = strlen(volume_info.domainname); 1767 + pSesInfo->domainName = 1768 + kmalloc(len + 1, GFP_KERNEL); 1769 + if(pSesInfo->domainName) 1770 + strcpy(pSesInfo->domainName, 1771 + volume_info.domainname); 1772 + } 1773 pSesInfo->linux_uid = volume_info.linux_uid; 1774 + pSesInfo->overrideSecFlg = volume_info.secFlg; 1775 down(&pSesInfo->sesSem); 1776 + /* BB FIXME need to pass vol->secFlgs BB */ 1777 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); 1778 up(&pSesInfo->sesSem); 1779 if(!rc) ··· 1980 1981 static int 1982 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, 1983 + char session_key[CIFS_SESS_KEY_SIZE], 1984 const struct nls_table *nls_codepage) 1985 { 1986 struct smb_hdr *smb_buffer; ··· 2038 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 2039 2040 pSMB->req_no_secext.CaseInsensitivePasswordLength = 2041 + cpu_to_le16(CIFS_SESS_KEY_SIZE); 2042 2043 pSMB->req_no_secext.CaseSensitivePasswordLength = 2044 + cpu_to_le16(CIFS_SESS_KEY_SIZE); 2045 bcc_ptr = pByteArea(smb_buffer); 2046 + memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE); 2047 + bcc_ptr += CIFS_SESS_KEY_SIZE; 2048 + memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE); 2049 + bcc_ptr += CIFS_SESS_KEY_SIZE; 2050 2051 if (ses->capabilities & CAP_UNICODE) { 2052 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */ ··· 2054 bcc_ptr++; 2055 } 2056 if(user == NULL) 2057 + bytes_returned = 0; /* skip null user */ 2058 else 2059 bytes_returned = 2060 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, ··· 2162 if (remaining_words > 0) { 2163 len = UniStrnlen((wchar_t *)bcc_ptr, 2164 remaining_words-1); 2165 + kfree(ses->serverNOS); 2166 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL); 2167 if(ses->serverNOS == NULL) 2168 goto sesssetup_nomem; ··· 2203 /* if these kcallocs fail not much we 2204 can do, but better to not fail the 2205 sesssetup itself */ 2206 + kfree(ses->serverDomain); 2207 ses->serverDomain = 2208 kzalloc(2, GFP_KERNEL); 2209 + kfree(ses->serverNOS); 2210 ses->serverNOS = 2211 kzalloc(2, GFP_KERNEL); 2212 } ··· 2217 if (((long) bcc_ptr + len) - (long) 2218 pByteArea(smb_buffer_response) 2219 <= BCC(smb_buffer_response)) { 2220 + kfree(ses->serverOS); 2221 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 2222 if(ses->serverOS == NULL) 2223 goto sesssetup_nomem; ··· 2229 bcc_ptr++; 2230 2231 len = strnlen(bcc_ptr, 1024); 2232 + kfree(ses->serverNOS); 2233 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); 2234 if(ses->serverNOS == NULL) 2235 goto sesssetup_nomem; ··· 2267 sesssetup_nomem: /* do not return an error on nomem for the info strings, 2268 since that could make reconnection harder, and 2269 reconnection might be needed to free memory */ 2270 if (smb_buffer) 2271 cifs_buf_release(smb_buffer); 2272 ··· 2635 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; 2636 if(sign_CIFS_PDUs) 2637 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; 2638 + /* if(ntlmv2_support) 2639 + negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/ 2640 /* setup pointers to domain name and workstation name */ 2641 bcc_ptr += SecurityBlobLength; 2642 ··· 2783 bcc_ptr, 2784 remaining_words 2785 - 1); 2786 + kfree(ses->serverNOS); 2787 ses->serverNOS = 2788 kzalloc(2 * (len + 1), 2789 GFP_KERNEL); ··· 2802 if (remaining_words > 0) { 2803 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2804 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2805 + kfree(ses->serverDomain); 2806 ses->serverDomain = 2807 kzalloc(2 * 2808 (len + ··· 2822 = 0; 2823 } /* else no more room so create dummy domain string */ 2824 else { 2825 + kfree(ses->serverDomain); 2826 ses->serverDomain = 2827 kzalloc(2, 2828 GFP_KERNEL); 2829 } 2830 } else { /* no room so create dummy domain and NOS string */ 2831 + kfree(ses->serverDomain); 2832 ses->serverDomain = 2833 kzalloc(2, GFP_KERNEL); 2834 + kfree(ses->serverNOS); 2835 ses->serverNOS = 2836 kzalloc(2, GFP_KERNEL); 2837 } ··· 2856 bcc_ptr++; 2857 2858 len = strnlen(bcc_ptr, 1024); 2859 + kfree(ses->serverNOS); 2860 ses->serverNOS = 2861 kzalloc(len + 1, 2862 GFP_KERNEL); ··· 2867 bcc_ptr++; 2868 2869 len = strnlen(bcc_ptr, 1024); 2870 + kfree(ses->serverDomain); 2871 ses->serverDomain = 2872 kzalloc(len + 1, 2873 GFP_KERNEL); ··· 2994 SecurityBlob->LmChallengeResponse.Buffer = 0; 2995 2996 SecurityBlob->NtChallengeResponse.Length = 2997 + cpu_to_le16(CIFS_SESS_KEY_SIZE); 2998 SecurityBlob->NtChallengeResponse.MaximumLength = 2999 + cpu_to_le16(CIFS_SESS_KEY_SIZE); 3000 + memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE); 3001 SecurityBlob->NtChallengeResponse.Buffer = 3002 cpu_to_le32(SecurityBlobLength); 3003 + SecurityBlobLength += CIFS_SESS_KEY_SIZE; 3004 + bcc_ptr += CIFS_SESS_KEY_SIZE; 3005 3006 if (ses->capabilities & CAP_UNICODE) { 3007 if (domain == NULL) { ··· 3190 bcc_ptr, 3191 remaining_words 3192 - 1); 3193 + kfree(ses->serverNOS); 3194 ses->serverNOS = 3195 kzalloc(2 * (len + 1), 3196 GFP_KERNEL); ··· 3244 if(ses->serverDomain) 3245 kfree(ses->serverDomain); 3246 ses->serverDomain = kzalloc(2, GFP_KERNEL); 3247 + kfree(ses->serverNOS); 3248 ses->serverNOS = kzalloc(2, GFP_KERNEL); 3249 } 3250 } else { /* ASCII */ ··· 3263 bcc_ptr++; 3264 3265 len = strnlen(bcc_ptr, 1024); 3266 + kfree(ses->serverNOS); 3267 ses->serverNOS = kzalloc(len+1,GFP_KERNEL); 3268 strncpy(ses->serverNOS, bcc_ptr, len); 3269 bcc_ptr += len; ··· 3340 bcc_ptr = &pSMB->Password[0]; 3341 if((ses->server->secMode) & SECMODE_USER) { 3342 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 3343 + *bcc_ptr = 0; /* password is null byte */ 3344 bcc_ptr++; /* skip password */ 3345 + /* already aligned so no need to do it below */ 3346 } else { 3347 + pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 3348 /* BB FIXME add code to fail this if NTLMv2 or Kerberos 3349 specified as required (when that support is added to 3350 the vfs in the future) as only NTLM or the much 3351 + weaker LANMAN (which we do not send by default) is accepted 3352 by Samba (not sure whether other servers allow 3353 NTLMv2 password here) */ 3354 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 3355 + if((extended_security & CIFSSEC_MAY_LANMAN) && 3356 + (ses->server->secType == LANMAN)) 3357 + calc_lanman_hash(ses, bcc_ptr); 3358 + else 3359 + #endif /* CIFS_WEAK_PW_HASH */ 3360 SMBNTencrypt(ses->password, 3361 ses->server->cryptKey, 3362 bcc_ptr); 3363 3364 + bcc_ptr += CIFS_SESS_KEY_SIZE; 3365 + if(ses->capabilities & CAP_UNICODE) { 3366 + /* must align unicode strings */ 3367 + *bcc_ptr = 0; /* null byte password */ 3368 + bcc_ptr++; 3369 + } 3370 } 3371 3372 if(ses->server->secMode & ··· 3429 } 3430 /* else do not bother copying these informational fields */ 3431 } 3432 + if(smb_buffer_response->WordCount == 3) 3433 + tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3434 + else 3435 + tcon->Flags = 0; 3436 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags)); 3437 } else if ((rc == 0) && tcon == NULL) { 3438 /* all we need to save for IPC$ connection */ ··· 3494 struct nls_table * nls_info) 3495 { 3496 int rc = 0; 3497 + char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 3498 int ntlmv2_flag = FALSE; 3499 int first_time = 0; 3500 ··· 3526 pSesInfo->server->secMode, 3527 pSesInfo->server->capabilities, 3528 pSesInfo->server->timeZone)); 3529 + if(experimEnabled < 2) 3530 + rc = CIFS_SessSetup(xid, pSesInfo, 3531 + first_time, nls_info); 3532 + else if (extended_security 3533 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3534 && (pSesInfo->server->secType == NTLMSSP)) { 3535 + rc = -EOPNOTSUPP; 3536 } else if (extended_security 3537 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3538 && (pSesInfo->server->secType == RawNTLMSSP)) {
+11 -4
fs/cifs/dir.c
··· 113 full_path[namelen+2] = 0; 114 BB remove above eight lines BB */ 115 116 - /* Inode operations in similar order to how they appear in the Linux file fs.h */ 117 118 int 119 cifs_create(struct inode *inode, struct dentry *direntry, int mode, ··· 178 FreeXid(xid); 179 return -ENOMEM; 180 } 181 - 182 - rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 183 desiredAccess, CREATE_NOT_DIR, 184 &fileHandle, &oplock, buf, cifs_sb->local_nls, 185 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 186 if(rc == -EIO) { 187 /* old server, retry the open legacy style */ 188 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, ··· 194 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 195 } 196 if (rc) { 197 - cFYI(1, ("cifs_create returned 0x%x ", rc)); 198 } else { 199 /* If Open reported that we actually created a file 200 then we now have to set the mode if possible */ ··· 372 cifs_sb->mnt_cifs_flags & 373 CIFS_MOUNT_MAP_SPECIAL_CHR); 374 375 if(!rc) { 376 /* BB Do not bother to decode buf since no 377 local inode yet to put timestamps in,
··· 113 full_path[namelen+2] = 0; 114 BB remove above eight lines BB */ 115 116 + /* Inode operations in similar order to how they appear in Linux file fs.h */ 117 118 int 119 cifs_create(struct inode *inode, struct dentry *direntry, int mode, ··· 178 FreeXid(xid); 179 return -ENOMEM; 180 } 181 + if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 182 + rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 183 desiredAccess, CREATE_NOT_DIR, 184 &fileHandle, &oplock, buf, cifs_sb->local_nls, 185 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 186 + else 187 + rc = -EIO; /* no NT SMB support fall into legacy open below */ 188 + 189 if(rc == -EIO) { 190 /* old server, retry the open legacy style */ 191 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, ··· 191 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 192 } 193 if (rc) { 194 + cFYI(1, ("cifs_create returned 0x%x", rc)); 195 } else { 196 /* If Open reported that we actually created a file 197 then we now have to set the mode if possible */ ··· 369 cifs_sb->mnt_cifs_flags & 370 CIFS_MOUNT_MAP_SPECIAL_CHR); 371 372 + /* BB FIXME - add handling for backlevel servers 373 + which need legacy open and check for all 374 + calls to SMBOpen for fallback to 375 + SMBLeagcyOpen */ 376 if(!rc) { 377 /* BB Do not bother to decode buf since no 378 local inode yet to put timestamps in,
+2 -2
fs/cifs/fcntl.c
··· 91 if(full_path == NULL) { 92 rc = -ENOMEM; 93 } else { 94 - cERROR(1,("cifs dir notify on file %s with arg 0x%lx",full_path,arg)); /* BB removeme BB */ 95 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 96 GENERIC_READ | SYNCHRONIZE, 0 /* create options */, 97 &netfid, &oplock,NULL, cifs_sb->local_nls, 98 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 99 /* BB fixme - add this handle to a notify handle list */ 100 if(rc) { 101 - cERROR(1,("Could not open directory for notify")); /* BB remove BB */ 102 } else { 103 filter = convert_to_cifs_notify_flags(arg); 104 if(filter != 0) {
··· 91 if(full_path == NULL) { 92 rc = -ENOMEM; 93 } else { 94 + cFYI(1,("dir notify on file %s Arg 0x%lx",full_path,arg)); 95 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 96 GENERIC_READ | SYNCHRONIZE, 0 /* create options */, 97 &netfid, &oplock,NULL, cifs_sb->local_nls, 98 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 99 /* BB fixme - add this handle to a notify handle list */ 100 if(rc) { 101 + cFYI(1,("Could not open directory for notify")); 102 } else { 103 filter = convert_to_cifs_notify_flags(arg); 104 if(filter != 0) {
+32 -20
fs/cifs/file.c
··· 110 &pCifsInode->openFileList); 111 } 112 write_unlock(&GlobalSMBSeslock); 113 - write_unlock(&file->f_owner.lock); 114 if (pCifsInode->clientCanCacheRead) { 115 /* we have the inode open somewhere else 116 no need to discard cache data */ ··· 200 } else { 201 if (file->f_flags & O_EXCL) 202 cERROR(1, ("could not find file instance for " 203 - "new file %p ", file)); 204 } 205 } 206 ··· 259 rc = -ENOMEM; 260 goto out; 261 } 262 - rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, 263 - CREATE_NOT_DIR, &netfid, &oplock, buf, 264 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 265 & CIFS_MOUNT_MAP_SPECIAL_CHR); 266 if (rc == -EIO) { 267 /* Old server, try legacy style OpenX */ 268 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, ··· 276 & CIFS_MOUNT_MAP_SPECIAL_CHR); 277 } 278 if (rc) { 279 - cFYI(1, ("cifs_open returned 0x%x ", rc)); 280 goto out; 281 } 282 file->private_data = ··· 286 goto out; 287 } 288 pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); 289 - write_lock(&file->f_owner.lock); 290 write_lock(&GlobalSMBSeslock); 291 list_add(&pCifsFile->tlist, &pTcon->openFileList); 292 ··· 296 &oplock, buf, full_path, xid); 297 } else { 298 write_unlock(&GlobalSMBSeslock); 299 - write_unlock(&file->f_owner.lock); 300 } 301 302 if (oplock & CIFS_CREATE_ACTION) { ··· 411 CIFS_MOUNT_MAP_SPECIAL_CHR); 412 if (rc) { 413 up(&pCifsFile->fh_sem); 414 - cFYI(1, ("cifs_open returned 0x%x ", rc)); 415 - cFYI(1, ("oplock: %d ", oplock)); 416 } else { 417 pCifsFile->netfid = netfid; 418 pCifsFile->invalidHandle = FALSE; ··· 474 pTcon = cifs_sb->tcon; 475 if (pSMBFile) { 476 pSMBFile->closePend = TRUE; 477 - write_lock(&file->f_owner.lock); 478 if (pTcon) { 479 /* no sense reconnecting to close a file that is 480 already closed */ ··· 488 the struct would be in each open file, 489 but this should give enough time to 490 clear the socket */ 491 - write_unlock(&file->f_owner.lock); 492 cERROR(1,("close with pending writes")); 493 msleep(timeout); 494 - write_lock(&file->f_owner.lock); 495 timeout *= 4; 496 } 497 - write_unlock(&file->f_owner.lock); 498 rc = CIFSSMBClose(xid, pTcon, 499 pSMBFile->netfid); 500 - write_lock(&file->f_owner.lock); 501 } 502 } 503 write_lock(&GlobalSMBSeslock); 504 list_del(&pSMBFile->flist); 505 list_del(&pSMBFile->tlist); 506 write_unlock(&GlobalSMBSeslock); 507 - write_unlock(&file->f_owner.lock); 508 kfree(pSMBFile->search_resume_name); 509 kfree(file->private_data); 510 file->private_data = NULL; ··· 527 (struct cifsFileInfo *)file->private_data; 528 char *ptmp; 529 530 - cFYI(1, ("Closedir inode = 0x%p with ", inode)); 531 532 xid = GetXid(); 533 ··· 601 } 602 if (pfLock->fl_flags & FL_ACCESS) 603 cFYI(1, ("Process suspended by mandatory locking - " 604 - "not implemented yet ")); 605 if (pfLock->fl_flags & FL_LEASE) 606 cFYI(1, ("Lease on file - not implemented yet")); 607 if (pfLock->fl_flags & ··· 1371 1372 xid = GetXid(); 1373 1374 - cFYI(1, ("Sync file - name: %s datasync: 0x%x ", 1375 dentry->d_name.name, datasync)); 1376 1377 rc = filemap_fdatawrite(inode->i_mapping); ··· 1400 /* fill in rpages then 1401 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ 1402 1403 - /* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index)); 1404 1405 #if 0 1406 if (rc < 0) ··· 1832 if (rc < 0) 1833 goto io_error; 1834 else 1835 - cFYI(1, ("Bytes read %d ",rc)); 1836 1837 file->f_dentry->d_inode->i_atime = 1838 current_fs_time(file->f_dentry->d_inode->i_sb); ··· 1945 struct address_space_operations cifs_addr_ops = { 1946 .readpage = cifs_readpage, 1947 .readpages = cifs_readpages, 1948 .writepage = cifs_writepage, 1949 .writepages = cifs_writepages, 1950 .prepare_write = cifs_prepare_write,
··· 110 &pCifsInode->openFileList); 111 } 112 write_unlock(&GlobalSMBSeslock); 113 if (pCifsInode->clientCanCacheRead) { 114 /* we have the inode open somewhere else 115 no need to discard cache data */ ··· 201 } else { 202 if (file->f_flags & O_EXCL) 203 cERROR(1, ("could not find file instance for " 204 + "new file %p", file)); 205 } 206 } 207 ··· 260 rc = -ENOMEM; 261 goto out; 262 } 263 + 264 + if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 265 + rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 266 + desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, 267 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 268 & CIFS_MOUNT_MAP_SPECIAL_CHR); 269 + else 270 + rc = -EIO; /* no NT SMB support fall into legacy open below */ 271 + 272 if (rc == -EIO) { 273 /* Old server, try legacy style OpenX */ 274 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, ··· 272 & CIFS_MOUNT_MAP_SPECIAL_CHR); 273 } 274 if (rc) { 275 + cFYI(1, ("cifs_open returned 0x%x", rc)); 276 goto out; 277 } 278 file->private_data = ··· 282 goto out; 283 } 284 pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); 285 write_lock(&GlobalSMBSeslock); 286 list_add(&pCifsFile->tlist, &pTcon->openFileList); 287 ··· 293 &oplock, buf, full_path, xid); 294 } else { 295 write_unlock(&GlobalSMBSeslock); 296 } 297 298 if (oplock & CIFS_CREATE_ACTION) { ··· 409 CIFS_MOUNT_MAP_SPECIAL_CHR); 410 if (rc) { 411 up(&pCifsFile->fh_sem); 412 + cFYI(1, ("cifs_open returned 0x%x", rc)); 413 + cFYI(1, ("oplock: %d", oplock)); 414 } else { 415 pCifsFile->netfid = netfid; 416 pCifsFile->invalidHandle = FALSE; ··· 472 pTcon = cifs_sb->tcon; 473 if (pSMBFile) { 474 pSMBFile->closePend = TRUE; 475 if (pTcon) { 476 /* no sense reconnecting to close a file that is 477 already closed */ ··· 487 the struct would be in each open file, 488 but this should give enough time to 489 clear the socket */ 490 cERROR(1,("close with pending writes")); 491 msleep(timeout); 492 timeout *= 4; 493 } 494 rc = CIFSSMBClose(xid, pTcon, 495 pSMBFile->netfid); 496 } 497 } 498 write_lock(&GlobalSMBSeslock); 499 list_del(&pSMBFile->flist); 500 list_del(&pSMBFile->tlist); 501 write_unlock(&GlobalSMBSeslock); 502 kfree(pSMBFile->search_resume_name); 503 kfree(file->private_data); 504 file->private_data = NULL; ··· 531 (struct cifsFileInfo *)file->private_data; 532 char *ptmp; 533 534 + cFYI(1, ("Closedir inode = 0x%p", inode)); 535 536 xid = GetXid(); 537 ··· 605 } 606 if (pfLock->fl_flags & FL_ACCESS) 607 cFYI(1, ("Process suspended by mandatory locking - " 608 + "not implemented yet")); 609 if (pfLock->fl_flags & FL_LEASE) 610 cFYI(1, ("Lease on file - not implemented yet")); 611 if (pfLock->fl_flags & ··· 1375 1376 xid = GetXid(); 1377 1378 + cFYI(1, ("Sync file - name: %s datasync: 0x%x", 1379 dentry->d_name.name, datasync)); 1380 1381 rc = filemap_fdatawrite(inode->i_mapping); ··· 1404 /* fill in rpages then 1405 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ 1406 1407 + /* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); 1408 1409 #if 0 1410 if (rc < 0) ··· 1836 if (rc < 0) 1837 goto io_error; 1838 else 1839 + cFYI(1, ("Bytes read %d",rc)); 1840 1841 file->f_dentry->d_inode->i_atime = 1842 current_fs_time(file->f_dentry->d_inode->i_sb); ··· 1949 struct address_space_operations cifs_addr_ops = { 1950 .readpage = cifs_readpage, 1951 .readpages = cifs_readpages, 1952 + .writepage = cifs_writepage, 1953 + .writepages = cifs_writepages, 1954 + .prepare_write = cifs_prepare_write, 1955 + .commit_write = cifs_commit_write, 1956 + .set_page_dirty = __set_page_dirty_nobuffers, 1957 + /* .sync_page = cifs_sync_page, */ 1958 + /* .direct_IO = */ 1959 + }; 1960 + 1961 + /* 1962 + * cifs_readpages requires the server to support a buffer large enough to 1963 + * contain the header plus one complete page of data. Otherwise, we need 1964 + * to leave cifs_readpages out of the address space operations. 1965 + */ 1966 + struct address_space_operations cifs_addr_ops_smallbuf = { 1967 + .readpage = cifs_readpage, 1968 .writepage = cifs_writepage, 1969 .writepages = cifs_writepages, 1970 .prepare_write = cifs_prepare_write,
+21 -18
fs/cifs/inode.c
··· 41 char *tmp_path; 42 43 pTcon = cifs_sb->tcon; 44 - cFYI(1, ("Getting info on %s ", search_path)); 45 /* could have done a find first instead but this returns more info */ 46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, 47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & ··· 97 inode = *pinode; 98 cifsInfo = CIFS_I(inode); 99 100 - cFYI(1, ("Old time %ld ", cifsInfo->time)); 101 cifsInfo->time = jiffies; 102 - cFYI(1, ("New time %ld ", cifsInfo->time)); 103 /* this is ok to set on every inode revalidate */ 104 atomic_set(&cifsInfo->inUse,1); 105 ··· 180 else /* not direct, send byte range locks */ 181 inode->i_fop = &cifs_file_ops; 182 183 - inode->i_data.a_ops = &cifs_addr_ops; 184 /* check if server can support readpages */ 185 if(pTcon->ses->server->maxBuf < 186 - 4096 + MAX_CIFS_HDR_SIZE) 187 - inode->i_data.a_ops->readpages = NULL; 188 } else if (S_ISDIR(inode->i_mode)) { 189 cFYI(1, ("Directory inode")); 190 inode->i_op = &cifs_dir_inode_ops; ··· 422 inode = *pinode; 423 cifsInfo = CIFS_I(inode); 424 cifsInfo->cifsAttrs = attr; 425 - cFYI(1, ("Old time %ld ", cifsInfo->time)); 426 cifsInfo->time = jiffies; 427 - cFYI(1, ("New time %ld ", cifsInfo->time)); 428 429 /* blksize needs to be multiple of two. So safer to default to 430 blksize and blkbits set in superblock so 2**blkbits and blksize 431 will match rather than setting to: 432 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 433 434 - /* Linux can not store file creation time unfortunately so we ignore it */ 435 inode->i_atime = 436 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); 437 inode->i_mtime = 438 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 439 inode->i_ctime = 440 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 441 - cFYI(0, ("Attributes came in as 0x%x ", attr)); 442 443 /* set default mode. will override for dirs below */ 444 if (atomic_read(&cifsInfo->inUse) == 0) ··· 520 else /* not direct, send byte range locks */ 521 inode->i_fop = &cifs_file_ops; 522 523 - inode->i_data.a_ops = &cifs_addr_ops; 524 if(pTcon->ses->server->maxBuf < 525 - 4096 + MAX_CIFS_HDR_SIZE) 526 - inode->i_data.a_ops->readpages = NULL; 527 } else if (S_ISDIR(inode->i_mode)) { 528 cFYI(1, ("Directory inode")); 529 inode->i_op = &cifs_dir_inode_ops; ··· 733 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, 734 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 735 if (rc) { 736 - cFYI(1, ("cifs_mkdir returned 0x%x ", rc)); 737 d_drop(direntry); 738 } else { 739 inode->i_nlink++; ··· 800 char *full_path = NULL; 801 struct cifsInodeInfo *cifsInode; 802 803 - cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode)); 804 805 xid = GetXid(); 806 ··· 1123 1124 xid = GetXid(); 1125 1126 - cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ", 1127 direntry->d_name.name, attrs->ia_valid)); 1128 1129 cifs_sb = CIFS_SB(direntry->d_inode->i_sb); ··· 1159 when the local oplock break takes longer to flush 1160 writebehind data than the SMB timeout for the SetPathInfo 1161 request would allow */ 1162 open_file = find_writable_file(cifsInode); 1163 if (open_file) { 1164 __u16 nfid = open_file->netfid; ··· 1292 it may be useful to Windows - but we do 1293 not want to set ctime unless some other 1294 timestamp is changing */ 1295 - cFYI(1, ("CIFS - CTIME changed ")); 1296 time_buf.ChangeTime = 1297 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); 1298 } else ··· 1359 1360 void cifs_delete_inode(struct inode *inode) 1361 { 1362 - cFYI(1, ("In cifs_delete_inode, inode = 0x%p ", inode)); 1363 /* may have to add back in if and when safe distributed caching of 1364 directories added e.g. via FindNotify */ 1365 }
··· 41 char *tmp_path; 42 43 pTcon = cifs_sb->tcon; 44 + cFYI(1, ("Getting info on %s", search_path)); 45 /* could have done a find first instead but this returns more info */ 46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, 47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & ··· 97 inode = *pinode; 98 cifsInfo = CIFS_I(inode); 99 100 + cFYI(1, ("Old time %ld", cifsInfo->time)); 101 cifsInfo->time = jiffies; 102 + cFYI(1, ("New time %ld", cifsInfo->time)); 103 /* this is ok to set on every inode revalidate */ 104 atomic_set(&cifsInfo->inUse,1); 105 ··· 180 else /* not direct, send byte range locks */ 181 inode->i_fop = &cifs_file_ops; 182 183 /* check if server can support readpages */ 184 if(pTcon->ses->server->maxBuf < 185 + PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 186 + inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 187 + else 188 + inode->i_data.a_ops = &cifs_addr_ops; 189 } else if (S_ISDIR(inode->i_mode)) { 190 cFYI(1, ("Directory inode")); 191 inode->i_op = &cifs_dir_inode_ops; ··· 421 inode = *pinode; 422 cifsInfo = CIFS_I(inode); 423 cifsInfo->cifsAttrs = attr; 424 + cFYI(1, ("Old time %ld", cifsInfo->time)); 425 cifsInfo->time = jiffies; 426 + cFYI(1, ("New time %ld", cifsInfo->time)); 427 428 /* blksize needs to be multiple of two. So safer to default to 429 blksize and blkbits set in superblock so 2**blkbits and blksize 430 will match rather than setting to: 431 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 432 433 + /* Linux can not store file creation time so ignore it */ 434 inode->i_atime = 435 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); 436 inode->i_mtime = 437 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 438 inode->i_ctime = 439 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 440 + cFYI(0, ("Attributes came in as 0x%x", attr)); 441 442 /* set default mode. will override for dirs below */ 443 if (atomic_read(&cifsInfo->inUse) == 0) ··· 519 else /* not direct, send byte range locks */ 520 inode->i_fop = &cifs_file_ops; 521 522 if(pTcon->ses->server->maxBuf < 523 + PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 524 + inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 525 + else 526 + inode->i_data.a_ops = &cifs_addr_ops; 527 } else if (S_ISDIR(inode->i_mode)) { 528 cFYI(1, ("Directory inode")); 529 inode->i_op = &cifs_dir_inode_ops; ··· 731 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, 732 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 733 if (rc) { 734 + cFYI(1, ("cifs_mkdir returned 0x%x", rc)); 735 d_drop(direntry); 736 } else { 737 inode->i_nlink++; ··· 798 char *full_path = NULL; 799 struct cifsInodeInfo *cifsInode; 800 801 + cFYI(1, ("cifs_rmdir, inode = 0x%p", inode)); 802 803 xid = GetXid(); 804 ··· 1121 1122 xid = GetXid(); 1123 1124 + cFYI(1, ("setattr on file %s attrs->iavalid 0x%x", 1125 direntry->d_name.name, attrs->ia_valid)); 1126 1127 cifs_sb = CIFS_SB(direntry->d_inode->i_sb); ··· 1157 when the local oplock break takes longer to flush 1158 writebehind data than the SMB timeout for the SetPathInfo 1159 request would allow */ 1160 + 1161 open_file = find_writable_file(cifsInode); 1162 if (open_file) { 1163 __u16 nfid = open_file->netfid; ··· 1289 it may be useful to Windows - but we do 1290 not want to set ctime unless some other 1291 timestamp is changing */ 1292 + cFYI(1, ("CIFS - CTIME changed")); 1293 time_buf.ChangeTime = 1294 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); 1295 } else ··· 1356 1357 void cifs_delete_inode(struct inode *inode) 1358 { 1359 + cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode)); 1360 /* may have to add back in if and when safe distributed caching of 1361 directories added e.g. via FindNotify */ 1362 }
+3 -4
fs/cifs/link.c
··· 167 return -ENOMEM; 168 } 169 170 - cFYI(1, ("Full path: %s ", full_path)); 171 cFYI(1, ("symname is %s", symname)); 172 173 /* BB what if DFS and this volume is on different share? BB */ ··· 186 inode->i_sb,xid); 187 188 if (rc != 0) { 189 - cFYI(1, 190 - ("Create symlink worked but get_inode_info failed with rc = %d ", 191 rc)); 192 } else { 193 if (pTcon->nocase) ··· 288 else { 289 cFYI(1,("num referral: %d",num_referrals)); 290 if(referrals) { 291 - cFYI(1,("referral string: %s ",referrals)); 292 strncpy(tmpbuffer, referrals, len-1); 293 } 294 }
··· 167 return -ENOMEM; 168 } 169 170 + cFYI(1, ("Full path: %s", full_path)); 171 cFYI(1, ("symname is %s", symname)); 172 173 /* BB what if DFS and this volume is on different share? BB */ ··· 186 inode->i_sb,xid); 187 188 if (rc != 0) { 189 + cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d", 190 rc)); 191 } else { 192 if (pTcon->nocase) ··· 289 else { 290 cFYI(1,("num referral: %d",num_referrals)); 291 if(referrals) { 292 + cFYI(1,("referral string: %s",referrals)); 293 strncpy(tmpbuffer, referrals, len-1); 294 } 295 }
+6 -4
fs/cifs/misc.c
··· 101 kfree(buf_to_free->serverDomain); 102 kfree(buf_to_free->serverNOS); 103 kfree(buf_to_free->password); 104 kfree(buf_to_free); 105 } 106 ··· 500 if(pSMBr->ByteCount > sizeof(struct file_notify_information)) { 501 data_offset = le32_to_cpu(pSMBr->DataOffset); 502 503 - pnotify = (struct file_notify_information *)((char *)&pSMBr->hdr.Protocol 504 - + data_offset); 505 - cFYI(1,("dnotify on %s with action: 0x%x",pnotify->FileName, 506 pnotify->Action)); /* BB removeme BB */ 507 - /* cifs_dump_mem("Received notify Data is: ",buf,sizeof(struct smb_hdr)+60); */ 508 return TRUE; 509 } 510 if(pSMBr->hdr.Status.CifsError) {
··· 101 kfree(buf_to_free->serverDomain); 102 kfree(buf_to_free->serverNOS); 103 kfree(buf_to_free->password); 104 + kfree(buf_to_free->domainName); 105 kfree(buf_to_free); 106 } 107 ··· 499 if(pSMBr->ByteCount > sizeof(struct file_notify_information)) { 500 data_offset = le32_to_cpu(pSMBr->DataOffset); 501 502 + pnotify = (struct file_notify_information *) 503 + ((char *)&pSMBr->hdr.Protocol + data_offset); 504 + cFYI(1,("dnotify on %s Action: 0x%x",pnotify->FileName, 505 pnotify->Action)); /* BB removeme BB */ 506 + /* cifs_dump_mem("Rcvd notify Data: ",buf, 507 + sizeof(struct smb_hdr)+60); */ 508 return TRUE; 509 } 510 if(pSMBr->hdr.Status.CifsError) {
+2 -2
fs/cifs/netmisc.c
··· 84 85 static const struct smb_to_posix_error mapping_table_ERRSRV[] = { 86 {ERRerror, -EIO}, 87 - {ERRbadpw, -EPERM}, 88 {ERRbadtype, -EREMOTE}, 89 {ERRaccess, -EACCES}, 90 {ERRinvtid, -ENXIO}, 91 - {ERRinvnetname, -ENODEV}, 92 {ERRinvdevice, -ENXIO}, 93 {ERRqfull, -ENOSPC}, 94 {ERRqtoobig, -ENOSPC},
··· 84 85 static const struct smb_to_posix_error mapping_table_ERRSRV[] = { 86 {ERRerror, -EIO}, 87 + {ERRbadpw, -EACCES}, /* was EPERM */ 88 {ERRbadtype, -EREMOTE}, 89 {ERRaccess, -EACCES}, 90 {ERRinvtid, -ENXIO}, 91 + {ERRinvnetname, -ENXIO}, 92 {ERRinvdevice, -ENXIO}, 93 {ERRqfull, -ENOSPC}, 94 {ERRqtoobig, -ENOSPC},
-143
fs/cifs/ntlmssp.c
··· 1 - /* 2 - * fs/cifs/ntlmssp.h 3 - * 4 - * Copyright (c) International Business Machines Corp., 2006 5 - * Author(s): Steve French (sfrench@us.ibm.com) 6 - * 7 - * This library is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU Lesser General Public License as published 9 - * by the Free Software Foundation; either version 2.1 of the License, or 10 - * (at your option) any later version. 11 - * 12 - * This library is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 - * the GNU Lesser General Public License for more details. 16 - * 17 - * You should have received a copy of the GNU Lesser General Public License 18 - * along with this library; if not, write to the Free Software 19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 - */ 21 - 22 - #include "cifspdu.h" 23 - #include "cifsglob.h" 24 - #include "cifsproto.h" 25 - #include "cifs_unicode.h" 26 - #include "cifs_debug.h" 27 - #include "ntlmssp.h" 28 - #include "nterr.h" 29 - 30 - #ifdef CONFIG_CIFS_EXPERIMENTAL 31 - static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) 32 - { 33 - __u32 capabilities = 0; 34 - 35 - /* init fields common to all four types of SessSetup */ 36 - /* note that header is initialized to zero in header_assemble */ 37 - pSMB->req.AndXCommand = 0xFF; 38 - pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 39 - pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 40 - 41 - /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ 42 - 43 - /* BB verify whether signing required on neg or just on auth frame 44 - (and NTLM case) */ 45 - 46 - capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 47 - CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; 48 - 49 - if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 50 - pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 51 - 52 - if (ses->capabilities & CAP_UNICODE) { 53 - pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE; 54 - capabilities |= CAP_UNICODE; 55 - } 56 - if (ses->capabilities & CAP_STATUS32) { 57 - pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS; 58 - capabilities |= CAP_STATUS32; 59 - } 60 - if (ses->capabilities & CAP_DFS) { 61 - pSMB->req.hdr.Flags2 |= SMBFLG2_DFS; 62 - capabilities |= CAP_DFS; 63 - } 64 - 65 - /* BB check whether to init vcnum BB */ 66 - return capabilities; 67 - } 68 - int 69 - CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type, 70 - int * pNTLMv2_flg, const struct nls_table *nls_cp) 71 - { 72 - int rc = 0; 73 - int wct; 74 - struct smb_hdr *smb_buffer; 75 - char *bcc_ptr; 76 - SESSION_SETUP_ANDX *pSMB; 77 - __u32 capabilities; 78 - 79 - if(ses == NULL) 80 - return -EINVAL; 81 - 82 - cFYI(1,("SStp type: %d",type)); 83 - if(type < CIFS_NTLM) { 84 - #ifndef CONFIG_CIFS_WEAK_PW_HASH 85 - /* LANMAN and plaintext are less secure and off by default. 86 - So we make this explicitly be turned on in kconfig (in the 87 - build) and turned on at runtime (changed from the default) 88 - in proc/fs/cifs or via mount parm. Unfortunately this is 89 - needed for old Win (e.g. Win95), some obscure NAS and OS/2 */ 90 - return -EOPNOTSUPP; 91 - #endif 92 - wct = 10; /* lanman 2 style sessionsetup */ 93 - } else if(type < CIFS_NTLMSSP_NEG) 94 - wct = 13; /* old style NTLM sessionsetup */ 95 - else /* same size for negotiate or auth, NTLMSSP or extended security */ 96 - wct = 12; 97 - 98 - rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses, 99 - (void **)&smb_buffer); 100 - if(rc) 101 - return rc; 102 - 103 - pSMB = (SESSION_SETUP_ANDX *)smb_buffer; 104 - 105 - capabilities = cifs_ssetup_hdr(ses, pSMB); 106 - bcc_ptr = pByteArea(smb_buffer); 107 - if(type > CIFS_NTLM) { 108 - pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 109 - capabilities |= CAP_EXTENDED_SECURITY; 110 - pSMB->req.Capabilities = cpu_to_le32(capabilities); 111 - /* BB set password lengths */ 112 - } else if(type < CIFS_NTLM) /* lanman */ { 113 - /* no capabilities flags in old lanman negotiation */ 114 - /* pSMB->old_req.PasswordLength = */ /* BB fixme BB */ 115 - } else /* type CIFS_NTLM */ { 116 - pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 117 - pSMB->req_no_secext.CaseInsensitivePasswordLength = 118 - cpu_to_le16(CIFS_SESSION_KEY_SIZE); 119 - pSMB->req_no_secext.CaseSensitivePasswordLength = 120 - cpu_to_le16(CIFS_SESSION_KEY_SIZE); 121 - } 122 - 123 - 124 - /* copy session key */ 125 - 126 - /* if Unicode, align strings to two byte boundary */ 127 - 128 - /* copy user name */ /* BB Do we need to special case null user name? */ 129 - 130 - /* copy domain name */ 131 - 132 - /* copy Linux version */ 133 - 134 - /* copy network operating system name */ 135 - 136 - /* update bcc and smb buffer length */ 137 - 138 - /* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */ 139 - /* SMB request buf freed in SendReceive2 */ 140 - 141 - return rc; 142 - } 143 - #endif /* CONFIG_CIFS_EXPERIMENTAL */
···
+130 -54
fs/cifs/readdir.c
··· 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 #include <linux/fs.h> 24 #include <linux/stat.h> 25 #include <linux/smp_lock.h> 26 #include "cifspdu.h" ··· 32 #include "cifs_fs_sb.h" 33 #include "cifsfs.h" 34 35 - /* BB fixme - add debug wrappers around this function to disable it fixme BB */ 36 - /* static void dump_cifs_file_struct(struct file *file, char *label) 37 { 38 struct cifsFileInfo * cf; 39 ··· 54 } 55 56 } 57 - } */ 58 59 /* Returns one if new inode created (which therefore needs to be hashed) */ 60 /* Might check in the future if inode number changed so we can rehash inode */ ··· 109 return rc; 110 } 111 112 - static void fill_in_inode(struct inode *tmp_inode, 113 - FILE_DIRECTORY_INFO *pfindData, int *pobject_type, int isNewInode) 114 { 115 loff_t local_size; 116 struct timespec local_mtime; 117 118 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); 119 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); 120 - __u32 attr = le32_to_cpu(pfindData->ExtFileAttributes); 121 - __u64 allocation_size = le64_to_cpu(pfindData->AllocationSize); 122 - __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile); 123 - 124 - cifsInfo->cifsAttrs = attr; 125 - cifsInfo->time = jiffies; 126 127 /* save mtime and size */ 128 local_mtime = tmp_inode->i_mtime; 129 local_size = tmp_inode->i_size; 130 131 /* Linux can not store file creation time unfortunately so ignore it */ 132 - tmp_inode->i_atime = 133 - cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); 134 - tmp_inode->i_mtime = 135 - cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 136 - tmp_inode->i_ctime = 137 - cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 138 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ 139 /* 2767 perms - indicate mandatory locking */ 140 /* BB fill in uid and gid here? with help from winbind? ··· 237 else 238 tmp_inode->i_fop = &cifs_file_ops; 239 240 - tmp_inode->i_data.a_ops = &cifs_addr_ops; 241 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 242 (cifs_sb->tcon->ses->server->maxBuf < 243 - 4096 + MAX_CIFS_HDR_SIZE)) 244 - tmp_inode->i_data.a_ops->readpages = NULL; 245 if(isNewInode) 246 return; /* No sense invalidating pages for new inode 247 since have not started caching readahead file ··· 362 else 363 tmp_inode->i_fop = &cifs_file_ops; 364 365 - tmp_inode->i_data.a_ops = &cifs_addr_ops; 366 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 367 (cifs_sb->tcon->ses->server->maxBuf < 368 - 4096 + MAX_CIFS_HDR_SIZE)) 369 - tmp_inode->i_data.a_ops->readpages = NULL; 370 371 if(isNewInode) 372 return; /* No sense invalidating pages for new inode since we ··· 440 ffirst_retry: 441 /* test for Unix extensions */ 442 if (pTcon->ses->capabilities & CAP_UNIX) { 443 - cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; 444 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 445 cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; 446 } else /* not srvinos - BB fixme add check for backlevel? */ { ··· 479 return len << 1; 480 } 481 482 - static char *nxt_dir_entry(char *old_entry, char *end_of_smb) 483 { 484 char * new_entry; 485 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; 486 487 - new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 488 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 489 /* validate that new_entry is not past end of SMB */ 490 if(new_entry >= end_of_smb) { ··· 499 ("search entry %p began after end of SMB %p old entry %p", 500 new_entry, end_of_smb, old_entry)); 501 return NULL; 502 - } else if (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb) { 503 cERROR(1,("search entry %p extends after end of SMB %p", 504 new_entry, end_of_smb)); 505 return NULL; ··· 520 char * filename = NULL; 521 int len = 0; 522 523 - if(cfile->srch_inf.info_level == 0x202) { 524 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 525 filename = &pFindData->FileName[0]; 526 if(cfile->srch_inf.unicode) { ··· 529 /* BB should we make this strnlen of PATH_MAX? */ 530 len = strnlen(filename, 5); 531 } 532 - } else if(cfile->srch_inf.info_level == 0x101) { 533 FILE_DIRECTORY_INFO * pFindData = 534 (FILE_DIRECTORY_INFO *)current_entry; 535 filename = &pFindData->FileName[0]; 536 len = le32_to_cpu(pFindData->FileNameLength); 537 - } else if(cfile->srch_inf.info_level == 0x102) { 538 FILE_FULL_DIRECTORY_INFO * pFindData = 539 (FILE_FULL_DIRECTORY_INFO *)current_entry; 540 filename = &pFindData->FileName[0]; 541 len = le32_to_cpu(pFindData->FileNameLength); 542 - } else if(cfile->srch_inf.info_level == 0x105) { 543 SEARCH_ID_FULL_DIR_INFO * pFindData = 544 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 545 filename = &pFindData->FileName[0]; 546 len = le32_to_cpu(pFindData->FileNameLength); 547 - } else if(cfile->srch_inf.info_level == 0x104) { 548 FILE_BOTH_DIRECTORY_INFO * pFindData = 549 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 550 filename = &pFindData->FileName[0]; 551 len = le32_to_cpu(pFindData->FileNameLength); 552 } else { ··· 643 . and .. for the root of a drive and for those we need 644 to start two entries earlier */ 645 646 - /* dump_cifs_file_struct(file, "In fce ");*/ 647 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 648 is_dir_changed(file)) || 649 (index_to_find < first_entry_in_buffer)) { ··· 692 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 693 - cifsFile->srch_inf.entries_in_buffer; 694 pos_in_buf = index_to_find - first_entry_in_buffer; 695 - cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 696 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 697 /* go entry by entry figuring out which is first */ 698 - current_entry = nxt_dir_entry(current_entry,end_of_smb); 699 } 700 if((current_entry == NULL) && (i < pos_in_buf)) { 701 /* BB fixme - check if we should flag this error */ ··· 724 /* inode num, inode type and filename returned */ 725 static int cifs_get_name_from_search_buf(struct qstr *pqst, 726 char *current_entry, __u16 level, unsigned int unicode, 727 - struct cifs_sb_info * cifs_sb, ino_t *pinum) 728 { 729 int rc = 0; 730 unsigned int len = 0; ··· 768 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 769 filename = &pFindData->FileName[0]; 770 len = le32_to_cpu(pFindData->FileNameLength); 771 } else { 772 cFYI(1,("Unknown findfirst level %d",level)); 773 return -EINVAL; 774 } 775 if(unicode) { 776 /* BB fixme - test with long names */ 777 /* Note converted filename can be longer than in unicode */ ··· 803 } 804 805 static int cifs_filldir(char *pfindEntry, struct file *file, 806 - filldir_t filldir, void *direntry, char *scratch_buf) 807 { 808 int rc = 0; 809 struct qstr qstring; ··· 839 rc = cifs_get_name_from_search_buf(&qstring,pfindEntry, 840 pCifsF->srch_inf.info_level, 841 pCifsF->srch_inf.unicode,cifs_sb, 842 &inum /* returned */); 843 844 if(rc) ··· 861 /* we pass in rc below, indicating whether it is a new inode, 862 so we can figure out whether to invalidate the inode cached 863 data if the file has changed */ 864 - if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) { 865 unix_fill_in_inode(tmp_inode, 866 - (FILE_UNIX_INFO *)pfindEntry,&obj_type, rc); 867 - } else { 868 - fill_in_inode(tmp_inode, 869 - (FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc); 870 - } 871 872 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos, 873 tmp_inode->i_ino,obj_type); ··· 930 filename = &pFindData->FileName[0]; 931 len = le32_to_cpu(pFindData->FileNameLength); 932 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 933 } else { 934 cFYI(1,("Unknown findfirst level %d",level)); 935 return -EINVAL; ··· 956 int num_to_fill = 0; 957 char * tmp_buf = NULL; 958 char * end_of_smb; 959 960 xid = GetXid(); 961 ··· 982 case 1: 983 if (filldir(direntry, "..", 2, file->f_pos, 984 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { 985 - cERROR(1, ("Filldir for parent dir failed ")); 986 rc = -ENOMEM; 987 break; 988 } ··· 1032 goto rddir2_exit; 1033 } 1034 cFYI(1,("loop through %d times filling dir for net buf %p", 1035 - num_to_fill,cifsFile->srch_inf.ntwrk_buf_start)); 1036 - end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 1037 - smbCalcSize((struct smb_hdr *) 1038 - cifsFile->srch_inf.ntwrk_buf_start); 1039 /* To be safe - for UCS to UTF-8 with strings loaded 1040 with the rare long characters alloc more to account for 1041 such multibyte target UTF-8 characters. cifs_unicode.c, ··· 1051 } 1052 /* if buggy server returns . and .. late do 1053 we want to check for that here? */ 1054 - rc = cifs_filldir(current_entry, file, 1055 - filldir, direntry,tmp_buf); 1056 file->f_pos++; 1057 - if(file->f_pos == cifsFile->srch_inf.index_of_last_entry) { 1058 cFYI(1,("last entry in buf at pos %lld %s", 1059 - file->f_pos,tmp_buf)); /* BB removeme BB */ 1060 cifs_save_resume_key(current_entry,cifsFile); 1061 break; 1062 } else 1063 - current_entry = nxt_dir_entry(current_entry, 1064 - end_of_smb); 1065 } 1066 kfree(tmp_buf); 1067 break;
··· 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 #include <linux/fs.h> 24 + #include <linux/pagemap.h> 25 #include <linux/stat.h> 26 #include <linux/smp_lock.h> 27 #include "cifspdu.h" ··· 31 #include "cifs_fs_sb.h" 32 #include "cifsfs.h" 33 34 + #ifdef CONFIG_CIFS_DEBUG2 35 + static void dump_cifs_file_struct(struct file *file, char *label) 36 { 37 struct cifsFileInfo * cf; 38 ··· 53 } 54 55 } 56 + } 57 + #endif /* DEBUG2 */ 58 59 /* Returns one if new inode created (which therefore needs to be hashed) */ 60 /* Might check in the future if inode number changed so we can rehash inode */ ··· 107 return rc; 108 } 109 110 + static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 111 + char * buf, int *pobject_type, int isNewInode) 112 { 113 loff_t local_size; 114 struct timespec local_mtime; 115 116 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); 117 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); 118 + __u32 attr; 119 + __u64 allocation_size; 120 + __u64 end_of_file; 121 122 /* save mtime and size */ 123 local_mtime = tmp_inode->i_mtime; 124 local_size = tmp_inode->i_size; 125 126 + if(new_buf_type) { 127 + FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf; 128 + 129 + attr = le32_to_cpu(pfindData->ExtFileAttributes); 130 + allocation_size = le64_to_cpu(pfindData->AllocationSize); 131 + end_of_file = le64_to_cpu(pfindData->EndOfFile); 132 + tmp_inode->i_atime = 133 + cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); 134 + tmp_inode->i_mtime = 135 + cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 136 + tmp_inode->i_ctime = 137 + cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 138 + } else { /* legacy, OS2 and DOS style */ 139 + FIND_FILE_STANDARD_INFO * pfindData = 140 + (FIND_FILE_STANDARD_INFO *)buf; 141 + 142 + attr = le16_to_cpu(pfindData->Attributes); 143 + allocation_size = le32_to_cpu(pfindData->AllocationSize); 144 + end_of_file = le32_to_cpu(pfindData->DataSize); 145 + tmp_inode->i_atime = CURRENT_TIME; 146 + /* tmp_inode->i_mtime = BB FIXME - add dos time handling 147 + tmp_inode->i_ctime = 0; BB FIXME */ 148 + 149 + } 150 + 151 /* Linux can not store file creation time unfortunately so ignore it */ 152 + 153 + cifsInfo->cifsAttrs = attr; 154 + cifsInfo->time = jiffies; 155 + 156 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ 157 /* 2767 perms - indicate mandatory locking */ 158 /* BB fill in uid and gid here? with help from winbind? ··· 215 else 216 tmp_inode->i_fop = &cifs_file_ops; 217 218 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 219 (cifs_sb->tcon->ses->server->maxBuf < 220 + PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 221 + tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 222 + else 223 + tmp_inode->i_data.a_ops = &cifs_addr_ops; 224 + 225 if(isNewInode) 226 return; /* No sense invalidating pages for new inode 227 since have not started caching readahead file ··· 338 else 339 tmp_inode->i_fop = &cifs_file_ops; 340 341 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 342 (cifs_sb->tcon->ses->server->maxBuf < 343 + PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 344 + tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 345 + else 346 + tmp_inode->i_data.a_ops = &cifs_addr_ops; 347 348 if(isNewInode) 349 return; /* No sense invalidating pages for new inode since we ··· 415 ffirst_retry: 416 /* test for Unix extensions */ 417 if (pTcon->ses->capabilities & CAP_UNIX) { 418 + cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; 419 + } else if ((pTcon->ses->capabilities & 420 + (CAP_NT_SMBS | CAP_NT_FIND)) == 0) { 421 + cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; 422 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 423 cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; 424 } else /* not srvinos - BB fixme add check for backlevel? */ { ··· 451 return len << 1; 452 } 453 454 + static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) 455 { 456 char * new_entry; 457 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; 458 459 + if(level == SMB_FIND_FILE_INFO_STANDARD) { 460 + FIND_FILE_STANDARD_INFO * pfData; 461 + pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; 462 + 463 + new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) + 464 + pfData->FileNameLength; 465 + } else 466 + new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 467 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 468 /* validate that new_entry is not past end of SMB */ 469 if(new_entry >= end_of_smb) { ··· 464 ("search entry %p began after end of SMB %p old entry %p", 465 new_entry, end_of_smb, old_entry)); 466 return NULL; 467 + } else if(((level == SMB_FIND_FILE_INFO_STANDARD) && 468 + (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || 469 + ((level != SMB_FIND_FILE_INFO_STANDARD) && 470 + (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { 471 cERROR(1,("search entry %p extends after end of SMB %p", 472 new_entry, end_of_smb)); 473 return NULL; ··· 482 char * filename = NULL; 483 int len = 0; 484 485 + if(cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { 486 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 487 filename = &pFindData->FileName[0]; 488 if(cfile->srch_inf.unicode) { ··· 491 /* BB should we make this strnlen of PATH_MAX? */ 492 len = strnlen(filename, 5); 493 } 494 + } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { 495 FILE_DIRECTORY_INFO * pFindData = 496 (FILE_DIRECTORY_INFO *)current_entry; 497 filename = &pFindData->FileName[0]; 498 len = le32_to_cpu(pFindData->FileNameLength); 499 + } else if(cfile->srch_inf.info_level == 500 + SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 501 FILE_FULL_DIRECTORY_INFO * pFindData = 502 (FILE_FULL_DIRECTORY_INFO *)current_entry; 503 filename = &pFindData->FileName[0]; 504 len = le32_to_cpu(pFindData->FileNameLength); 505 + } else if(cfile->srch_inf.info_level == 506 + SMB_FIND_FILE_ID_FULL_DIR_INFO) { 507 SEARCH_ID_FULL_DIR_INFO * pFindData = 508 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 509 filename = &pFindData->FileName[0]; 510 len = le32_to_cpu(pFindData->FileNameLength); 511 + } else if(cfile->srch_inf.info_level == 512 + SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 513 FILE_BOTH_DIRECTORY_INFO * pFindData = 514 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 515 + filename = &pFindData->FileName[0]; 516 + len = le32_to_cpu(pFindData->FileNameLength); 517 + } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { 518 + FIND_FILE_STANDARD_INFO * pFindData = 519 + (FIND_FILE_STANDARD_INFO *)current_entry; 520 filename = &pFindData->FileName[0]; 521 len = le32_to_cpu(pFindData->FileNameLength); 522 } else { ··· 597 . and .. for the root of a drive and for those we need 598 to start two entries earlier */ 599 600 + #ifdef CONFIG_CIFS_DEBUG2 601 + dump_cifs_file_struct(file, "In fce "); 602 + #endif 603 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 604 is_dir_changed(file)) || 605 (index_to_find < first_entry_in_buffer)) { ··· 644 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 645 - cifsFile->srch_inf.entries_in_buffer; 646 pos_in_buf = index_to_find - first_entry_in_buffer; 647 + cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 648 + 649 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 650 /* go entry by entry figuring out which is first */ 651 + current_entry = nxt_dir_entry(current_entry,end_of_smb, 652 + cifsFile->srch_inf.info_level); 653 } 654 if((current_entry == NULL) && (i < pos_in_buf)) { 655 /* BB fixme - check if we should flag this error */ ··· 674 /* inode num, inode type and filename returned */ 675 static int cifs_get_name_from_search_buf(struct qstr *pqst, 676 char *current_entry, __u16 level, unsigned int unicode, 677 + struct cifs_sb_info * cifs_sb, int max_len, ino_t *pinum) 678 { 679 int rc = 0; 680 unsigned int len = 0; ··· 718 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 719 filename = &pFindData->FileName[0]; 720 len = le32_to_cpu(pFindData->FileNameLength); 721 + } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 722 + FIND_FILE_STANDARD_INFO * pFindData = 723 + (FIND_FILE_STANDARD_INFO *)current_entry; 724 + filename = &pFindData->FileName[0]; 725 + /* one byte length, no name conversion */ 726 + len = (unsigned int)pFindData->FileNameLength; 727 } else { 728 cFYI(1,("Unknown findfirst level %d",level)); 729 return -EINVAL; 730 } 731 + 732 + if(len > max_len) { 733 + cERROR(1,("bad search response length %d past smb end", len)); 734 + return -EINVAL; 735 + } 736 + 737 if(unicode) { 738 /* BB fixme - test with long names */ 739 /* Note converted filename can be longer than in unicode */ ··· 741 } 742 743 static int cifs_filldir(char *pfindEntry, struct file *file, 744 + filldir_t filldir, void *direntry, char *scratch_buf, int max_len) 745 { 746 int rc = 0; 747 struct qstr qstring; ··· 777 rc = cifs_get_name_from_search_buf(&qstring,pfindEntry, 778 pCifsF->srch_inf.info_level, 779 pCifsF->srch_inf.unicode,cifs_sb, 780 + max_len, 781 &inum /* returned */); 782 783 if(rc) ··· 798 /* we pass in rc below, indicating whether it is a new inode, 799 so we can figure out whether to invalidate the inode cached 800 data if the file has changed */ 801 + if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 802 unix_fill_in_inode(tmp_inode, 803 + (FILE_UNIX_INFO *)pfindEntry, 804 + &obj_type, rc); 805 + else if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 806 + fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */, 807 + pfindEntry, &obj_type, rc); 808 + else 809 + fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc); 810 + 811 812 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos, 813 tmp_inode->i_ino,obj_type); ··· 864 filename = &pFindData->FileName[0]; 865 len = le32_to_cpu(pFindData->FileNameLength); 866 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 867 + } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 868 + FIND_FILE_STANDARD_INFO * pFindData = 869 + (FIND_FILE_STANDARD_INFO *)current_entry; 870 + filename = &pFindData->FileName[0]; 871 + /* one byte length, no name conversion */ 872 + len = (unsigned int)pFindData->FileNameLength; 873 } else { 874 cFYI(1,("Unknown findfirst level %d",level)); 875 return -EINVAL; ··· 884 int num_to_fill = 0; 885 char * tmp_buf = NULL; 886 char * end_of_smb; 887 + int max_len; 888 889 xid = GetXid(); 890 ··· 909 case 1: 910 if (filldir(direntry, "..", 2, file->f_pos, 911 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { 912 + cERROR(1, ("Filldir for parent dir failed")); 913 rc = -ENOMEM; 914 break; 915 } ··· 959 goto rddir2_exit; 960 } 961 cFYI(1,("loop through %d times filling dir for net buf %p", 962 + num_to_fill,cifsFile->srch_inf.ntwrk_buf_start)); 963 + max_len = smbCalcSize((struct smb_hdr *) 964 + cifsFile->srch_inf.ntwrk_buf_start); 965 + end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len; 966 + 967 /* To be safe - for UCS to UTF-8 with strings loaded 968 with the rare long characters alloc more to account for 969 such multibyte target UTF-8 characters. cifs_unicode.c, ··· 977 } 978 /* if buggy server returns . and .. late do 979 we want to check for that here? */ 980 + rc = cifs_filldir(current_entry, file, 981 + filldir, direntry, tmp_buf, max_len); 982 file->f_pos++; 983 + if(file->f_pos == 984 + cifsFile->srch_inf.index_of_last_entry) { 985 cFYI(1,("last entry in buf at pos %lld %s", 986 + file->f_pos,tmp_buf)); 987 cifs_save_resume_key(current_entry,cifsFile); 988 break; 989 } else 990 + current_entry = 991 + nxt_dir_entry(current_entry, end_of_smb, 992 + cifsFile->srch_inf.info_level); 993 } 994 kfree(tmp_buf); 995 break;
+538
fs/cifs/sess.c
···
··· 1 + /* 2 + * fs/cifs/sess.c 3 + * 4 + * SMB/CIFS session setup handling routines 5 + * 6 + * Copyright (c) International Business Machines Corp., 2006 7 + * Author(s): Steve French (sfrench@us.ibm.com) 8 + * 9 + * This library is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU Lesser General Public License as published 11 + * by the Free Software Foundation; either version 2.1 of the License, or 12 + * (at your option) any later version. 13 + * 14 + * This library is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 + * the GNU Lesser General Public License for more details. 18 + * 19 + * You should have received a copy of the GNU Lesser General Public License 20 + * along with this library; if not, write to the Free Software 21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 + */ 23 + 24 + #include "cifspdu.h" 25 + #include "cifsglob.h" 26 + #include "cifsproto.h" 27 + #include "cifs_unicode.h" 28 + #include "cifs_debug.h" 29 + #include "ntlmssp.h" 30 + #include "nterr.h" 31 + #include <linux/utsname.h> 32 + 33 + extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 34 + unsigned char *p24); 35 + 36 + static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) 37 + { 38 + __u32 capabilities = 0; 39 + 40 + /* init fields common to all four types of SessSetup */ 41 + /* note that header is initialized to zero in header_assemble */ 42 + pSMB->req.AndXCommand = 0xFF; 43 + pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 44 + pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 45 + 46 + /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ 47 + 48 + /* BB verify whether signing required on neg or just on auth frame 49 + (and NTLM case) */ 50 + 51 + capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 52 + CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; 53 + 54 + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 55 + pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 56 + 57 + if (ses->capabilities & CAP_UNICODE) { 58 + pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE; 59 + capabilities |= CAP_UNICODE; 60 + } 61 + if (ses->capabilities & CAP_STATUS32) { 62 + pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS; 63 + capabilities |= CAP_STATUS32; 64 + } 65 + if (ses->capabilities & CAP_DFS) { 66 + pSMB->req.hdr.Flags2 |= SMBFLG2_DFS; 67 + capabilities |= CAP_DFS; 68 + } 69 + if (ses->capabilities & CAP_UNIX) { 70 + capabilities |= CAP_UNIX; 71 + } 72 + 73 + /* BB check whether to init vcnum BB */ 74 + return capabilities; 75 + } 76 + 77 + static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 78 + const struct nls_table * nls_cp) 79 + { 80 + char * bcc_ptr = *pbcc_area; 81 + int bytes_ret = 0; 82 + 83 + /* BB FIXME add check that strings total less 84 + than 335 or will need to send them as arrays */ 85 + 86 + /* unicode strings, must be word aligned before the call */ 87 + /* if ((long) bcc_ptr % 2) { 88 + *bcc_ptr = 0; 89 + bcc_ptr++; 90 + } */ 91 + /* copy user */ 92 + if(ses->userName == NULL) { 93 + /* BB what about null user mounts - check that we do this BB */ 94 + } else { /* 300 should be long enough for any conceivable user name */ 95 + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName, 96 + 300, nls_cp); 97 + } 98 + bcc_ptr += 2 * bytes_ret; 99 + bcc_ptr += 2; /* account for null termination */ 100 + /* copy domain */ 101 + if(ses->domainName == NULL) 102 + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, 103 + "CIFS_LINUX_DOM", 32, nls_cp); 104 + else 105 + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 106 + 256, nls_cp); 107 + bcc_ptr += 2 * bytes_ret; 108 + bcc_ptr += 2; /* account for null terminator */ 109 + 110 + /* Copy OS version */ 111 + bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32, 112 + nls_cp); 113 + bcc_ptr += 2 * bytes_ret; 114 + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 115 + 32, nls_cp); 116 + bcc_ptr += 2 * bytes_ret; 117 + bcc_ptr += 2; /* trailing null */ 118 + 119 + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 120 + 32, nls_cp); 121 + bcc_ptr += 2 * bytes_ret; 122 + bcc_ptr += 2; /* trailing null */ 123 + 124 + *pbcc_area = bcc_ptr; 125 + } 126 + 127 + static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 128 + const struct nls_table * nls_cp) 129 + { 130 + char * bcc_ptr = *pbcc_area; 131 + 132 + /* copy user */ 133 + /* BB what about null user mounts - check that we do this BB */ 134 + /* copy user */ 135 + if(ses->userName == NULL) { 136 + /* BB what about null user mounts - check that we do this BB */ 137 + } else { /* 300 should be long enough for any conceivable user name */ 138 + strncpy(bcc_ptr, ses->userName, 300); 139 + } 140 + /* BB improve check for overflow */ 141 + bcc_ptr += strnlen(ses->userName, 300); 142 + *bcc_ptr = 0; 143 + bcc_ptr++; /* account for null termination */ 144 + 145 + /* copy domain */ 146 + 147 + if(ses->domainName == NULL) { 148 + strcpy(bcc_ptr, "CIFS_LINUX_DOM"); 149 + bcc_ptr += 14; /* strlen(CIFS_LINUX_DOM) */ 150 + } else { 151 + strncpy(bcc_ptr, ses->domainName, 256); 152 + bcc_ptr += strnlen(ses->domainName, 256); 153 + } 154 + *bcc_ptr = 0; 155 + bcc_ptr++; 156 + 157 + /* BB check for overflow here */ 158 + 159 + strcpy(bcc_ptr, "Linux version "); 160 + bcc_ptr += strlen("Linux version "); 161 + strcpy(bcc_ptr, system_utsname.release); 162 + bcc_ptr += strlen(system_utsname.release) + 1; 163 + 164 + strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); 165 + bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; 166 + 167 + *pbcc_area = bcc_ptr; 168 + } 169 + 170 + static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 171 + const struct nls_table * nls_cp) 172 + { 173 + int rc = 0; 174 + int words_left, len; 175 + char * data = *pbcc_area; 176 + 177 + 178 + 179 + cFYI(1,("bleft %d",bleft)); 180 + 181 + 182 + /* word align, if bytes remaining is not even */ 183 + if(bleft % 2) { 184 + bleft--; 185 + data++; 186 + } 187 + words_left = bleft / 2; 188 + 189 + /* save off server operating system */ 190 + len = UniStrnlen((wchar_t *) data, words_left); 191 + 192 + /* We look for obvious messed up bcc or strings in response so we do not go off 193 + the end since (at least) WIN2K and Windows XP have a major bug in not null 194 + terminating last Unicode string in response */ 195 + if(len >= words_left) 196 + return rc; 197 + 198 + if(ses->serverOS) 199 + kfree(ses->serverOS); 200 + /* UTF-8 string will not grow more than four times as big as UCS-16 */ 201 + ses->serverOS = kzalloc(4 * len, GFP_KERNEL); 202 + if(ses->serverOS != NULL) { 203 + cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, 204 + nls_cp); 205 + } 206 + data += 2 * (len + 1); 207 + words_left -= len + 1; 208 + 209 + /* save off server network operating system */ 210 + len = UniStrnlen((wchar_t *) data, words_left); 211 + 212 + if(len >= words_left) 213 + return rc; 214 + 215 + if(ses->serverNOS) 216 + kfree(ses->serverNOS); 217 + ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ 218 + if(ses->serverNOS != NULL) { 219 + cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 220 + nls_cp); 221 + if(strncmp(ses->serverNOS, "NT LAN Manager 4",16) == 0) { 222 + cFYI(1,("NT4 server")); 223 + ses->flags |= CIFS_SES_NT4; 224 + } 225 + } 226 + data += 2 * (len + 1); 227 + words_left -= len + 1; 228 + 229 + /* save off server domain */ 230 + len = UniStrnlen((wchar_t *) data, words_left); 231 + 232 + if(len > words_left) 233 + return rc; 234 + 235 + if(ses->serverDomain) 236 + kfree(ses->serverDomain); 237 + ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ 238 + if(ses->serverDomain != NULL) { 239 + cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 240 + nls_cp); 241 + ses->serverDomain[2*len] = 0; 242 + ses->serverDomain[(2*len) + 1] = 0; 243 + } 244 + data += 2 * (len + 1); 245 + words_left -= len + 1; 246 + 247 + cFYI(1,("words left: %d",words_left)); 248 + 249 + return rc; 250 + } 251 + 252 + static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 253 + const struct nls_table * nls_cp) 254 + { 255 + int rc = 0; 256 + int len; 257 + char * bcc_ptr = *pbcc_area; 258 + 259 + cFYI(1,("decode sessetup ascii. bleft %d", bleft)); 260 + 261 + len = strnlen(bcc_ptr, bleft); 262 + if(len >= bleft) 263 + return rc; 264 + 265 + if(ses->serverOS) 266 + kfree(ses->serverOS); 267 + 268 + ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 269 + if(ses->serverOS) 270 + strncpy(ses->serverOS, bcc_ptr, len); 271 + 272 + bcc_ptr += len + 1; 273 + bleft -= len + 1; 274 + 275 + len = strnlen(bcc_ptr, bleft); 276 + if(len >= bleft) 277 + return rc; 278 + 279 + if(ses->serverNOS) 280 + kfree(ses->serverNOS); 281 + 282 + ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); 283 + if(ses->serverNOS) 284 + strncpy(ses->serverNOS, bcc_ptr, len); 285 + 286 + bcc_ptr += len + 1; 287 + bleft -= len + 1; 288 + 289 + len = strnlen(bcc_ptr, bleft); 290 + if(len > bleft) 291 + return rc; 292 + 293 + if(ses->serverDomain) 294 + kfree(ses->serverDomain); 295 + 296 + ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); 297 + if(ses->serverOS) 298 + strncpy(ses->serverOS, bcc_ptr, len); 299 + 300 + bcc_ptr += len + 1; 301 + bleft -= len + 1; 302 + 303 + cFYI(1,("ascii: bytes left %d",bleft)); 304 + 305 + return rc; 306 + } 307 + 308 + int 309 + CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 310 + const struct nls_table *nls_cp) 311 + { 312 + int rc = 0; 313 + int wct; 314 + struct smb_hdr *smb_buf; 315 + char *bcc_ptr; 316 + char *str_area; 317 + SESSION_SETUP_ANDX *pSMB; 318 + __u32 capabilities; 319 + int count; 320 + int resp_buf_type = 0; 321 + struct kvec iov[2]; 322 + enum securityEnum type; 323 + __u16 action; 324 + int bytes_remaining; 325 + 326 + if(ses == NULL) 327 + return -EINVAL; 328 + 329 + type = ses->server->secType; 330 + 331 + cFYI(1,("sess setup type %d",type)); 332 + if(type == LANMAN) { 333 + #ifndef CONFIG_CIFS_WEAK_PW_HASH 334 + /* LANMAN and plaintext are less secure and off by default. 335 + So we make this explicitly be turned on in kconfig (in the 336 + build) and turned on at runtime (changed from the default) 337 + in proc/fs/cifs or via mount parm. Unfortunately this is 338 + needed for old Win (e.g. Win95), some obscure NAS and OS/2 */ 339 + return -EOPNOTSUPP; 340 + #endif 341 + wct = 10; /* lanman 2 style sessionsetup */ 342 + } else if((type == NTLM) || (type == NTLMv2)) { 343 + /* For NTLMv2 failures eventually may need to retry NTLM */ 344 + wct = 13; /* old style NTLM sessionsetup */ 345 + } else /* same size for negotiate or auth, NTLMSSP or extended security */ 346 + wct = 12; 347 + 348 + rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses, 349 + (void **)&smb_buf); 350 + if(rc) 351 + return rc; 352 + 353 + pSMB = (SESSION_SETUP_ANDX *)smb_buf; 354 + 355 + capabilities = cifs_ssetup_hdr(ses, pSMB); 356 + 357 + /* we will send the SMB in two pieces, 358 + a fixed length beginning part, and a 359 + second part which will include the strings 360 + and rest of bcc area, in order to avoid having 361 + to do a large buffer 17K allocation */ 362 + iov[0].iov_base = (char *)pSMB; 363 + iov[0].iov_len = smb_buf->smb_buf_length + 4; 364 + 365 + /* 2000 big enough to fit max user, domain, NOS name etc. */ 366 + str_area = kmalloc(2000, GFP_KERNEL); 367 + bcc_ptr = str_area; 368 + 369 + if(type == LANMAN) { 370 + #ifdef CONFIG_CIFS_WEAK_PW_HASH 371 + char lnm_session_key[CIFS_SESS_KEY_SIZE]; 372 + 373 + /* no capabilities flags in old lanman negotiation */ 374 + 375 + pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; 376 + /* BB calculate hash with password */ 377 + /* and copy into bcc */ 378 + 379 + calc_lanman_hash(ses, lnm_session_key); 380 + 381 + /* #ifdef CONFIG_CIFS_DEBUG2 382 + cifs_dump_mem("cryptkey: ",ses->server->cryptKey, 383 + CIFS_SESS_KEY_SIZE); 384 + #endif */ 385 + memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); 386 + bcc_ptr += CIFS_SESS_KEY_SIZE; 387 + 388 + /* can not sign if LANMAN negotiated so no need 389 + to calculate signing key? but what if server 390 + changed to do higher than lanman dialect and 391 + we reconnected would we ever calc signing_key? */ 392 + 393 + cFYI(1,("Negotiating LANMAN setting up strings")); 394 + /* Unicode not allowed for LANMAN dialects */ 395 + ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 396 + #endif 397 + } else if (type == NTLM) { 398 + char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 399 + 400 + pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 401 + pSMB->req_no_secext.CaseInsensitivePasswordLength = 402 + cpu_to_le16(CIFS_SESS_KEY_SIZE); 403 + pSMB->req_no_secext.CaseSensitivePasswordLength = 404 + cpu_to_le16(CIFS_SESS_KEY_SIZE); 405 + 406 + /* calculate session key */ 407 + SMBNTencrypt(ses->password, ses->server->cryptKey, 408 + ntlm_session_key); 409 + 410 + if(first_time) /* should this be moved into common code 411 + with similar ntlmv2 path? */ 412 + cifs_calculate_mac_key(ses->server->mac_signing_key, 413 + ntlm_session_key, ses->password); 414 + /* copy session key */ 415 + 416 + memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); 417 + bcc_ptr += CIFS_SESS_KEY_SIZE; 418 + memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); 419 + bcc_ptr += CIFS_SESS_KEY_SIZE; 420 + if(ses->capabilities & CAP_UNICODE) { 421 + /* unicode strings must be word aligned */ 422 + if (iov[0].iov_len % 2) { 423 + *bcc_ptr = 0; 424 + bcc_ptr++; 425 + } 426 + unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 427 + } else 428 + ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 429 + } else if (type == NTLMv2) { 430 + char * v2_sess_key = 431 + kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL); 432 + 433 + /* BB FIXME change all users of v2_sess_key to 434 + struct ntlmv2_resp */ 435 + 436 + if(v2_sess_key == NULL) { 437 + cifs_small_buf_release(smb_buf); 438 + return -ENOMEM; 439 + } 440 + 441 + pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 442 + 443 + /* LM2 password would be here if we supported it */ 444 + pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; 445 + /* cpu_to_le16(LM2_SESS_KEY_SIZE); */ 446 + 447 + pSMB->req_no_secext.CaseSensitivePasswordLength = 448 + cpu_to_le16(sizeof(struct ntlmv2_resp)); 449 + 450 + /* calculate session key */ 451 + setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 452 + if(first_time) /* should this be moved into common code 453 + with similar ntlmv2 path? */ 454 + /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, 455 + response BB FIXME, v2_sess_key); */ 456 + 457 + /* copy session key */ 458 + 459 + /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); 460 + bcc_ptr += LM2_SESS_KEY_SIZE; */ 461 + memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp)); 462 + bcc_ptr += sizeof(struct ntlmv2_resp); 463 + kfree(v2_sess_key); 464 + if(ses->capabilities & CAP_UNICODE) { 465 + if(iov[0].iov_len % 2) { 466 + *bcc_ptr = 0; 467 + } bcc_ptr++; 468 + unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 469 + } else 470 + ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 471 + } else /* NTLMSSP or SPNEGO */ { 472 + pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 473 + capabilities |= CAP_EXTENDED_SECURITY; 474 + pSMB->req.Capabilities = cpu_to_le32(capabilities); 475 + /* BB set password lengths */ 476 + } 477 + 478 + count = (long) bcc_ptr - (long) str_area; 479 + smb_buf->smb_buf_length += count; 480 + 481 + BCC_LE(smb_buf) = cpu_to_le16(count); 482 + 483 + iov[1].iov_base = str_area; 484 + iov[1].iov_len = count; 485 + rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); 486 + /* SMB request buf freed in SendReceive2 */ 487 + 488 + cFYI(1,("ssetup rc from sendrecv2 is %d",rc)); 489 + if(rc) 490 + goto ssetup_exit; 491 + 492 + pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; 493 + smb_buf = (struct smb_hdr *)iov[0].iov_base; 494 + 495 + if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) { 496 + rc = -EIO; 497 + cERROR(1,("bad word count %d", smb_buf->WordCount)); 498 + goto ssetup_exit; 499 + } 500 + action = le16_to_cpu(pSMB->resp.Action); 501 + if (action & GUEST_LOGIN) 502 + cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */ 503 + ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */ 504 + cFYI(1, ("UID = %d ", ses->Suid)); 505 + /* response can have either 3 or 4 word count - Samba sends 3 */ 506 + /* and lanman response is 3 */ 507 + bytes_remaining = BCC(smb_buf); 508 + bcc_ptr = pByteArea(smb_buf); 509 + 510 + if(smb_buf->WordCount == 4) { 511 + __u16 blob_len; 512 + blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); 513 + bcc_ptr += blob_len; 514 + if(blob_len > bytes_remaining) { 515 + cERROR(1,("bad security blob length %d", blob_len)); 516 + rc = -EINVAL; 517 + goto ssetup_exit; 518 + } 519 + bytes_remaining -= blob_len; 520 + } 521 + 522 + /* BB check if Unicode and decode strings */ 523 + if(smb_buf->Flags2 & SMBFLG2_UNICODE) 524 + rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 525 + ses, nls_cp); 526 + else 527 + rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp); 528 + 529 + ssetup_exit: 530 + kfree(str_area); 531 + if(resp_buf_type == CIFS_SMALL_BUFFER) { 532 + cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base)); 533 + cifs_small_buf_release(iov[0].iov_base); 534 + } else if(resp_buf_type == CIFS_LARGE_BUFFER) 535 + cifs_buf_release(iov[0].iov_base); 536 + 537 + return rc; 538 + }
+1
fs/cifs/smbencrypt.c
··· 30 #include <linux/random.h> 31 #include "cifs_unicode.h" 32 #include "cifspdu.h" 33 #include "md5.h" 34 #include "cifs_debug.h" 35 #include "cifsencrypt.h"
··· 30 #include <linux/random.h> 31 #include "cifs_unicode.h" 32 #include "cifspdu.h" 33 + #include "cifsglob.h" 34 #include "md5.h" 35 #include "cifs_debug.h" 36 #include "cifsencrypt.h"
+1 -2
fs/cifs/transport.c
··· 654 655 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 656 up(&ses->server->tcpSem); 657 - cERROR(1, 658 - ("Illegal length, greater than maximum frame, %d ", 659 in_buf->smb_buf_length)); 660 DeleteMidQEntry(midQ); 661 /* If not lock req, update # of requests on wire to server */
··· 654 655 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 656 up(&ses->server->tcpSem); 657 + cERROR(1, ("Illegal length, greater than maximum frame, %d", 658 in_buf->smb_buf_length)); 659 DeleteMidQEntry(midQ); 660 /* If not lock req, update # of requests on wire to server */