Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+729 -183
+10
fs/cifs/CHANGES
··· 1 + Version 1.40 2 + ------------ 3 + Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance 4 + of readpages by eliminating one extra memcpy. Allow update of file size 5 + from remote server even if file is open for write as long as mount is 6 + directio. Recognize share mode security and send NTLM encrypted password 7 + on tree connect if share mode negotiated. 8 + 1 9 Version 1.39 2 10 ------------ 3 11 Defer close of a file handle slightly if pending writes depend on that handle ··· 15 7 CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative 16 8 dentries so files that the client sees as deleted but that later get created 17 9 on the server will be recognized. Add client side permission check on setattr. 10 + Timeout stuck requests better (where server has never responded or sent corrupt 11 + responses) 18 12 19 13 Version 1.38 20 14 ------------
+11 -1
fs/cifs/README
··· 436 436 SFU does). In the future the bottom 9 bits of the mode 437 437 mode also will be emulated using queries of the security 438 438 descriptor (ACL). 439 - 439 + sec Security mode. Allowed values are: 440 + none attempt to connection as a null user (no name) 441 + krb5 Use Kerberos version 5 authentication 442 + krb5i Use Kerberos authentication and packet signing 443 + ntlm Use NTLM password hashing (default) 444 + ntlmi Use NTLM password hashing with signing (if 445 + /proc/fs/cifs/PacketSigningEnabled on or if 446 + server requires signing also can be the default) 447 + ntlmv2 Use NTLMv2 password hashing 448 + ntlmv2i Use NTLMv2 password hashing with packet signing 449 + 440 450 The mount.cifs mount helper also accepts a few mount options before -o 441 451 including: 442 452
+31 -20
fs/cifs/cifs_debug.c
··· 219 219 220 220 if (c == '1' || c == 'y' || c == 'Y' || c == '0') { 221 221 read_lock(&GlobalSMBSeslock); 222 + #ifdef CONFIG_CIFS_STATS2 223 + atomic_set(&totBufAllocCount, 0); 224 + atomic_set(&totSmBufAllocCount, 0); 225 + #endif /* CONFIG_CIFS_STATS2 */ 222 226 list_for_each(tmp, &GlobalTreeConnectionList) { 223 227 tcon = list_entry(tmp, struct cifsTconInfo, 224 228 cifsConnectionList); ··· 280 276 smBufAllocCount.counter,cifs_min_small); 281 277 length += item_length; 282 278 buf += item_length; 279 + #ifdef CONFIG_CIFS_STATS2 280 + item_length = sprintf(buf, "Total Large %d Small %d Allocations\n", 281 + atomic_read(&totBufAllocCount), 282 + atomic_read(&totSmBufAllocCount)); 283 + length += item_length; 284 + buf += item_length; 285 + #endif /* CONFIG_CIFS_STATS2 */ 286 + 283 287 item_length = 284 288 sprintf(buf,"Operations (MIDs): %d\n", 285 289 midCount.counter); ··· 401 389 static write_proc_t ntlmv2_enabled_write; 402 390 static read_proc_t packet_signing_enabled_read; 403 391 static write_proc_t packet_signing_enabled_write; 404 - static read_proc_t quotaEnabled_read; 405 - static write_proc_t quotaEnabled_write; 392 + static read_proc_t experimEnabled_read; 393 + static write_proc_t experimEnabled_write; 406 394 static read_proc_t linuxExtensionsEnabled_read; 407 395 static write_proc_t linuxExtensionsEnabled_write; 408 396 ··· 442 430 pde->write_proc = oplockEnabled_write; 443 431 444 432 pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs, 445 - quotaEnabled_read, NULL); 433 + experimEnabled_read, NULL); 446 434 if (pde) 447 - pde->write_proc = quotaEnabled_write; 435 + pde->write_proc = experimEnabled_write; 448 436 449 437 pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs, 450 438 linuxExtensionsEnabled_read, NULL); ··· 586 574 } 587 575 588 576 static int 589 - quotaEnabled_read(char *page, char **start, off_t off, 577 + experimEnabled_read(char *page, char **start, off_t off, 590 578 int count, int *eof, void *data) 591 579 { 592 580 int len; 593 581 594 582 len = sprintf(page, "%d\n", experimEnabled); 595 - /* could also check if quotas are enabled in kernel 596 - as a whole first */ 583 + 597 584 len -= off; 598 585 *start = page + off; 599 586 ··· 607 596 return len; 608 597 } 609 598 static int 610 - quotaEnabled_write(struct file *file, const char __user *buffer, 599 + experimEnabled_write(struct file *file, const char __user *buffer, 611 600 unsigned long count, void *data) 612 601 { 613 - char c; 614 - int rc; 602 + char c; 603 + int rc; 615 604 616 - rc = get_user(c, buffer); 617 - if (rc) 618 - return rc; 619 - if (c == '0' || c == 'n' || c == 'N') 620 - experimEnabled = 0; 621 - else if (c == '1' || c == 'y' || c == 'Y') 622 - experimEnabled = 1; 605 + rc = get_user(c, buffer); 606 + if (rc) 607 + return rc; 608 + if (c == '0' || c == 'n' || c == 'N') 609 + experimEnabled = 0; 610 + else if (c == '1' || c == 'y' || c == 'Y') 611 + experimEnabled = 1; 612 + else if (c == '2') 613 + experimEnabled = 2; 623 614 624 - return count; 615 + return count; 625 616 } 626 617 627 618 static int ··· 633 620 int len; 634 621 635 622 len = sprintf(page, "%d\n", linuxExtEnabled); 636 - /* could also check if quotas are enabled in kernel 637 - as a whole first */ 638 623 len -= off; 639 624 *start = page + off; 640 625
+3 -2
fs/cifs/cifs_fs_sb.h
··· 24 24 #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ 25 25 #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ 26 26 #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ 27 - #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ 28 - #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ 27 + #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ 28 + #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ 29 29 #define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ 30 + #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ 30 31 31 32 struct cifs_sb_info { 32 33 struct cifsTconInfo *tcon; /* primary mount */
+38
fs/cifs/cifsacl.h
··· 1 + /* 2 + * fs/cifs/cifsacl.h 3 + * 4 + * Copyright (c) International Business Machines Corp., 2005 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 + #ifndef _CIFSACL_H 23 + #define _CIFSACL_H 24 + 25 + struct cifs_sid { 26 + __u8 revision; /* revision level */ 27 + __u8 num_subauths; 28 + __u8 authority[6]; 29 + __u32 sub_auth[4]; 30 + /* next sub_auth if any ... */ 31 + } __attribute__((packed)); 32 + 33 + /* everyone */ 34 + extern const struct cifs_sid sid_everyone; 35 + /* group users */ 36 + extern const struct cifs_sid sid_user; 37 + 38 + #endif /* _CIFSACL_H */
+54 -1
fs/cifs/cifsencrypt.c
··· 1 1 /* 2 2 * fs/cifs/cifsencrypt.c 3 3 * 4 - * Copyright (C) International Business Machines Corp., 2003 4 + * Copyright (C) International Business Machines Corp., 2005 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 80 80 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 81 81 82 82 return rc; 83 + } 84 + 85 + static int cifs_calc_signature2(const struct kvec * iov, int n_vec, 86 + const char * key, char * signature) 87 + { 88 + struct MD5Context context; 89 + 90 + if((iov == NULL) || (signature == NULL)) 91 + return -EINVAL; 92 + 93 + MD5Init(&context); 94 + MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); 95 + 96 + /* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ 97 + 98 + MD5Final(signature,&context); 99 + 100 + return -EOPNOTSUPP; 101 + /* return 0; */ 102 + } 103 + 104 + 105 + int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server, 106 + __u32 * pexpected_response_sequence_number) 107 + { 108 + int rc = 0; 109 + char smb_signature[20]; 110 + struct smb_hdr * cifs_pdu = iov[0].iov_base; 111 + 112 + if((cifs_pdu == NULL) || (server == NULL)) 113 + return -EINVAL; 114 + 115 + if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 116 + return rc; 117 + 118 + spin_lock(&GlobalMid_Lock); 119 + cifs_pdu->Signature.Sequence.SequenceNumber = 120 + cpu_to_le32(server->sequence_number); 121 + cifs_pdu->Signature.Sequence.Reserved = 0; 122 + 123 + *pexpected_response_sequence_number = server->sequence_number++; 124 + server->sequence_number++; 125 + spin_unlock(&GlobalMid_Lock); 126 + 127 + rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key, 128 + smb_signature); 129 + if(rc) 130 + memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 131 + else 132 + memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 133 + 134 + return rc; 135 + 83 136 } 84 137 85 138 int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
+24 -4
fs/cifs/cifsfs.c
··· 513 513 return written; 514 514 } 515 515 516 + static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) 517 + { 518 + /* origin == SEEK_END => we must revalidate the cached file length */ 519 + if (origin == 2) { 520 + int retval = cifs_revalidate(file->f_dentry); 521 + if (retval < 0) 522 + return (loff_t)retval; 523 + } 524 + return remote_llseek(file, offset, origin); 525 + } 526 + 516 527 static struct file_system_type cifs_fs_type = { 517 528 .owner = THIS_MODULE, 518 529 .name = "cifs", ··· 597 586 .flush = cifs_flush, 598 587 .mmap = cifs_file_mmap, 599 588 .sendfile = generic_file_sendfile, 589 + .llseek = cifs_llseek, 600 590 #ifdef CONFIG_CIFS_POSIX 601 591 .ioctl = cifs_ioctl, 602 592 #endif /* CONFIG_CIFS_POSIX */ ··· 621 609 #ifdef CONFIG_CIFS_POSIX 622 610 .ioctl = cifs_ioctl, 623 611 #endif /* CONFIG_CIFS_POSIX */ 624 - 612 + .llseek = cifs_llseek, 625 613 #ifdef CONFIG_CIFS_EXPERIMENTAL 626 614 .dir_notify = cifs_dir_notify, 627 615 #endif /* CONFIG_CIFS_EXPERIMENTAL */ ··· 639 627 .flush = cifs_flush, 640 628 .mmap = cifs_file_mmap, 641 629 .sendfile = generic_file_sendfile, 630 + .llseek = cifs_llseek, 642 631 #ifdef CONFIG_CIFS_POSIX 643 632 .ioctl = cifs_ioctl, 644 633 #endif /* CONFIG_CIFS_POSIX */ ··· 662 649 #ifdef CONFIG_CIFS_POSIX 663 650 .ioctl = cifs_ioctl, 664 651 #endif /* CONFIG_CIFS_POSIX */ 665 - 652 + .llseek = cifs_llseek, 666 653 #ifdef CONFIG_CIFS_EXPERIMENTAL 667 654 .dir_notify = cifs_dir_notify, 668 655 #endif /* CONFIG_CIFS_EXPERIMENTAL */ ··· 746 733 kmem_cache_destroy(cifs_req_cachep); 747 734 return -ENOMEM; 748 735 } 749 - /* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and 736 + /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and 750 737 almost all handle based requests (but not write response, nor is it 751 738 sufficient for path based requests). A smaller size would have 752 739 been more efficient (compacting multiple slab items on one 4k page) ··· 755 742 efficient to alloc 1 per page off the slab compared to 17K (5page) 756 743 alloc of large cifs buffers even when page debugging is on */ 757 744 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq", 758 - MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); 745 + MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN, 746 + NULL, NULL); 759 747 if (cifs_sm_req_cachep == NULL) { 760 748 mempool_destroy(cifs_req_poolp); 761 749 kmem_cache_destroy(cifs_req_cachep); ··· 968 954 atomic_set(&tconInfoReconnectCount, 0); 969 955 970 956 atomic_set(&bufAllocCount, 0); 957 + atomic_set(&smBufAllocCount, 0); 958 + #ifdef CONFIG_CIFS_STATS2 959 + atomic_set(&totBufAllocCount, 0); 960 + atomic_set(&totSmBufAllocCount, 0); 961 + #endif /* CONFIG_CIFS_STATS2 */ 962 + 971 963 atomic_set(&midCount, 0); 972 964 GlobalCurrentXid = 0; 973 965 GlobalTotalActiveXid = 0;
+1 -1
fs/cifs/cifsfs.h
··· 99 99 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 100 100 extern int cifs_ioctl (struct inode * inode, struct file * filep, 101 101 unsigned int command, unsigned long arg); 102 - #define CIFS_VERSION "1.39" 102 + #define CIFS_VERSION "1.40" 103 103 #endif /* _CIFSFS_H */
+15 -3
fs/cifs/cifsglob.h
··· 233 233 atomic_t num_hardlinks; 234 234 atomic_t num_symlinks; 235 235 atomic_t num_locks; 236 + atomic_t num_acl_get; 237 + atomic_t num_acl_set; 236 238 #ifdef CONFIG_CIFS_STATS2 237 239 unsigned long long time_writes; 238 240 unsigned long long time_reads; ··· 287 285 unsigned endOfSearch:1; 288 286 unsigned emptyDir:1; 289 287 unsigned unicode:1; 288 + unsigned smallBuf:1; /* so we know which buf_release function to call */ 290 289 }; 291 290 292 291 struct cifsFileInfo { ··· 423 420 #define MID_RESPONSE_RECEIVED 4 424 421 #define MID_RETRY_NEEDED 8 /* session closed while this request out */ 425 422 #define MID_NO_RESP_NEEDED 0x10 426 - #define MID_SMALL_BUFFER 0x20 /* 112 byte response buffer instead of 4K */ 423 + 424 + /* Types of response buffer returned from SendReceive2 */ 425 + #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ 426 + #define CIFS_SMALL_BUFFER 1 427 + #define CIFS_LARGE_BUFFER 2 428 + #define CIFS_IOVEC 4 /* array of response buffers */ 427 429 428 430 /* 429 431 ***************************************************************** ··· 513 505 GLOBAL_EXTERN atomic_t tconInfoReconnectCount; 514 506 515 507 /* Various Debug counters to remove someday (BB) */ 516 - GLOBAL_EXTERN atomic_t bufAllocCount; 517 - GLOBAL_EXTERN atomic_t smBufAllocCount; 508 + GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */ 509 + #ifdef CONFIG_CIFS_STATS2 510 + GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */ 511 + GLOBAL_EXTERN atomic_t totSmBufAllocCount; 512 + #endif 513 + GLOBAL_EXTERN atomic_t smBufAllocCount; 518 514 GLOBAL_EXTERN atomic_t midCount; 519 515 520 516 /* Misc globals */
+84 -13
fs/cifs/cifspdu.h
··· 1 1 /* 2 2 * fs/cifs/cifspdu.h 3 3 * 4 - * Copyright (c) International Business Machines Corp., 2002 4 + * Copyright (c) International Business Machines Corp., 2002,2005 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 80 80 #define NT_TRANSACT_GET_USER_QUOTA 0x07 81 81 #define NT_TRANSACT_SET_USER_QUOTA 0x08 82 82 83 - #define MAX_CIFS_HDR_SIZE 256 /* is future chained NTCreateXReadX bigger? */ 83 + #define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */ 84 + /* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */ 85 + /* among the requests (NTCreateX response is bigger with wct of 34) */ 86 + #define MAX_CIFS_HDR_SIZE 0x58 /* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */ 87 + #define CIFS_SMALL_PATH 120 /* allows for (448-88)/3 */ 84 88 85 89 /* internal cifs vfs structures */ 86 90 /***************************************************************** ··· 528 524 /* STRING PrimaryDomain */ 529 525 /* STRING NativeOS */ 530 526 /* STRING NativeLanMan */ 531 - } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) request format */ 527 + } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) req format */ 532 528 533 529 struct { /* default (NTLM) response format */ 534 530 struct smb_hdr hdr; /* wct = 3 */ ··· 540 536 unsigned char NativeOS[1]; /* followed by */ 541 537 /* unsigned char * NativeLanMan; */ 542 538 /* unsigned char * PrimaryDomain; */ 543 - } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response format */ 539 + } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response */ 544 540 } __attribute__((packed)) SESSION_SETUP_ANDX; 545 541 546 542 #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" ··· 1007 1003 1008 1004 /* empty wct response to setattr */ 1009 1005 1010 - /***************************************************/ 1011 - /* NT Transact structure defintions follow */ 1012 - /* Currently only ioctl and notify are implemented */ 1013 - /***************************************************/ 1006 + /*******************************************************/ 1007 + /* NT Transact structure defintions follow */ 1008 + /* Currently only ioctl, acl (get security descriptor) */ 1009 + /* and notify are implemented */ 1010 + /*******************************************************/ 1011 + typedef struct smb_com_ntransact_req { 1012 + struct smb_hdr hdr; /* wct >= 19 */ 1013 + __u8 MaxSetupCount; 1014 + __u16 Reserved; 1015 + __le32 TotalParameterCount; 1016 + __le32 TotalDataCount; 1017 + __le32 MaxParameterCount; 1018 + __le32 MaxDataCount; 1019 + __le32 ParameterCount; 1020 + __le32 ParameterOffset; 1021 + __le32 DataCount; 1022 + __le32 DataOffset; 1023 + __u8 SetupCount; /* four setup words follow subcommand */ 1024 + /* SNIA spec incorrectly included spurious pad here */ 1025 + __le16 SubCommand; /* 2 = IOCTL/FSCTL */ 1026 + /* SetupCount words follow then */ 1027 + __le16 ByteCount; 1028 + __u8 Pad[3]; 1029 + __u8 Parms[0]; 1030 + } __attribute__((packed)) NTRANSACT_REQ; 1031 + 1032 + typedef struct smb_com_ntransact_rsp { 1033 + struct smb_hdr hdr; /* wct = 18 */ 1034 + __u8 Reserved[3]; 1035 + __le32 TotalParameterCount; 1036 + __le32 TotalDataCount; 1037 + __le32 ParameterCount; 1038 + __le32 ParameterOffset; 1039 + __le32 ParameterDisplacement; 1040 + __le32 DataCount; 1041 + __le32 DataOffset; 1042 + __le32 DataDisplacement; 1043 + __u8 SetupCount; /* 0 */ 1044 + __u16 ByteCount; 1045 + /* __u8 Pad[3]; */ 1046 + /* parms and data follow */ 1047 + } __attribute__((packed)) NTRANSACT_RSP; 1048 + 1014 1049 typedef struct smb_com_transaction_ioctl_req { 1015 1050 struct smb_hdr hdr; /* wct = 23 */ 1016 1051 __u8 MaxSetupCount; ··· 1064 1021 __le32 DataOffset; 1065 1022 __u8 SetupCount; /* four setup words follow subcommand */ 1066 1023 /* SNIA spec incorrectly included spurious pad here */ 1067 - __le16 SubCommand;/* 2 = IOCTL/FSCTL */ 1024 + __le16 SubCommand; /* 2 = IOCTL/FSCTL */ 1068 1025 __le32 FunctionCode; 1069 1026 __u16 Fid; 1070 - __u8 IsFsctl; /* 1 = File System Control, 0 = device control (IOCTL)*/ 1071 - __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS share)*/ 1027 + __u8 IsFsctl; /* 1 = File System Control 0 = device control (IOCTL) */ 1028 + __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS) */ 1072 1029 __le16 ByteCount; 1073 1030 __u8 Pad[3]; 1074 1031 __u8 Data[1]; ··· 1088 1045 __u8 SetupCount; /* 1 */ 1089 1046 __le16 ReturnedDataLen; 1090 1047 __u16 ByteCount; 1091 - __u8 Pad[3]; 1092 1048 } __attribute__((packed)) TRANSACT_IOCTL_RSP; 1049 + 1050 + #define CIFS_ACL_OWNER 1 1051 + #define CIFS_ACL_GROUP 2 1052 + #define CIFS_ACL_DACL 4 1053 + #define CIFS_ACL_SACL 8 1054 + 1055 + typedef struct smb_com_transaction_qsec_req { 1056 + struct smb_hdr hdr; /* wct = 19 */ 1057 + __u8 MaxSetupCount; 1058 + __u16 Reserved; 1059 + __le32 TotalParameterCount; 1060 + __le32 TotalDataCount; 1061 + __le32 MaxParameterCount; 1062 + __le32 MaxDataCount; 1063 + __le32 ParameterCount; 1064 + __le32 ParameterOffset; 1065 + __le32 DataCount; 1066 + __le32 DataOffset; 1067 + __u8 SetupCount; /* no setup words follow subcommand */ 1068 + /* SNIA spec incorrectly included spurious pad here */ 1069 + __le16 SubCommand; /* 6 = QUERY_SECURITY_DESC */ 1070 + __le16 ByteCount; /* bcc = 3 + 8 */ 1071 + __u8 Pad[3]; 1072 + __u16 Fid; 1073 + __u16 Reserved2; 1074 + __le32 AclFlags; 1075 + } __attribute__((packed)) QUERY_SEC_DESC_REQ; 1093 1076 1094 1077 typedef struct smb_com_transaction_change_notify_req { 1095 1078 struct smb_hdr hdr; /* wct = 23 */ ··· 1137 1068 __u8 WatchTree; /* 1 = Monitor subdirectories */ 1138 1069 __u8 Reserved2; 1139 1070 __le16 ByteCount; 1140 - /* __u8 Pad[3];*/ 1071 + /* __u8 Pad[3];*/ 1141 1072 /* __u8 Data[1];*/ 1142 1073 } __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; 1143 1074 1075 + /* BB eventually change to use generic ntransact rsp struct 1076 + and validation routine */ 1144 1077 typedef struct smb_com_transaction_change_notify_rsp { 1145 1078 struct smb_hdr hdr; /* wct = 18 */ 1146 1079 __u8 Reserved[3];
+14 -9
fs/cifs/cifsproto.h
··· 48 48 struct smb_hdr * /* out */ , 49 49 int * /* bytes returned */ , const int long_op); 50 50 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 51 - struct kvec *, int /* nvec */, 52 - int * /* bytes returned */ , const int long_op); 51 + struct kvec *, int /* nvec to send */, 52 + int * /* type of buf returned */ , const int long_op); 53 53 extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); 54 54 extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); 55 55 extern int is_valid_oplock_break(struct smb_hdr *smb); ··· 93 93 const struct nls_table *); 94 94 95 95 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 96 - const char *searchName, const struct nls_table *nls_codepage, 97 - __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep); 96 + const char *searchName, const struct nls_table *nls_codepage, 97 + __u16 *searchHandle, struct cifs_search_info * psrch_inf, 98 + int map, const char dirsep); 98 99 99 100 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 100 - __u16 searchHandle, struct cifs_search_info * psrch_inf); 101 + __u16 searchHandle, struct cifs_search_info * psrch_inf); 101 102 102 103 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, 103 104 const __u16 search_handle); ··· 231 230 const int smb_file_id); 232 231 233 232 extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 234 - const int netfid, unsigned int count, 235 - const __u64 lseek, unsigned int *nbytes, char **buf); 233 + const int netfid, unsigned int count, 234 + const __u64 lseek, unsigned int *nbytes, char **buf, 235 + int * return_buf_type); 236 236 extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 237 237 const int netfid, const unsigned int count, 238 238 const __u64 lseek, unsigned int *nbytes, 239 239 const char *buf, const char __user *ubuf, 240 240 const int long_op); 241 - #ifdef CONFIG_CIFS_EXPERIMENTAL 242 241 extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 243 242 const int netfid, const unsigned int count, 244 243 const __u64 offset, unsigned int *nbytes, 245 244 struct kvec *iov, const int nvec, const int long_op); 246 - #endif /* CONFIG_CIFS_EXPERIMENTAL */ 247 245 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 248 246 const unsigned char *searchName, __u64 * inode_number, 249 247 const struct nls_table *nls_codepage, ··· 269 269 extern int cifs_reconnect(struct TCP_Server_Info *server); 270 270 271 271 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); 272 + extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 273 + __u32 *); 272 274 extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, 273 275 __u32 expected_sequence_number); 274 276 extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); ··· 299 297 const char *fileName, const char * ea_name, 300 298 const void * ea_value, const __u16 ea_value_len, 301 299 const struct nls_table *nls_codepage, int remap_special_chars); 300 + extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, 301 + __u16 fid, char *acl_inf, const int buflen, 302 + const int acl_type /* ACCESS vs. DEFAULT */); 302 303 extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 303 304 const unsigned char *searchName, 304 305 char *acl_inf, const int buflen,const int acl_type,
+247 -47
fs/cifs/cifssmb.c
··· 37 37 #include "cifsproto.h" 38 38 #include "cifs_unicode.h" 39 39 #include "cifs_debug.h" 40 + #include "cifsacl.h" 40 41 41 42 #ifdef CONFIG_CIFS_POSIX 42 43 static struct { ··· 373 372 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 374 373 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 375 374 if (rc == 0) { 376 - server->secMode = pSMBr->SecurityMode; 377 - server->secType = NTLM; /* BB override default for 375 + server->secMode = pSMBr->SecurityMode; 376 + if((server->secMode & SECMODE_USER) == 0) 377 + cFYI(1,("share mode security")); 378 + server->secType = NTLM; /* BB override default for 378 379 NTLMv2 or kerberos v5 */ 379 380 /* one byte - no need to convert this or EncryptionKeyLen 380 381 from little endian */ ··· 386 383 min(le32_to_cpu(pSMBr->MaxBufferSize), 387 384 (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 388 385 server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); 389 - cFYI(0, ("Max buf = %d ", ses->server->maxBuf)); 386 + cFYI(0, ("Max buf = %d", ses->server->maxBuf)); 390 387 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); 391 388 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 392 389 server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); ··· 414 411 (server->server_GUID, 415 412 pSMBr->u.extended_response. 416 413 GUID, 16) != 0) { 417 - cFYI(1, 418 - ("UID of server does not match previous connection to same ip address")); 414 + cFYI(1, ("server UID changed")); 419 415 memcpy(server-> 420 416 server_GUID, 421 417 pSMBr->u. ··· 960 958 return rc; 961 959 } 962 960 963 - /* If no buffer passed in, then caller wants to do the copy 964 - as in the case of readpages so the SMB buffer must be 965 - freed by the caller */ 966 - 967 961 int 968 962 CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 969 - const int netfid, const unsigned int count, 970 - const __u64 lseek, unsigned int *nbytes, char **buf) 963 + const int netfid, const unsigned int count, 964 + const __u64 lseek, unsigned int *nbytes, char **buf, 965 + int * pbuf_type) 971 966 { 972 967 int rc = -EACCES; 973 968 READ_REQ *pSMB = NULL; 974 969 READ_RSP *pSMBr = NULL; 975 970 char *pReadData = NULL; 976 - int bytes_returned; 977 971 int wct; 972 + int resp_buf_type = 0; 973 + struct kvec iov[1]; 978 974 979 975 cFYI(1,("Reading %d bytes on fid %d",count,netfid)); 980 976 if(tcon->ses->capabilities & CAP_LARGE_FILES) ··· 981 981 wct = 10; /* old style read */ 982 982 983 983 *nbytes = 0; 984 - rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB, 985 - (void **) &pSMBr); 984 + rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); 986 985 if (rc) 987 986 return rc; 988 987 ··· 989 990 if (tcon->ses->server == NULL) 990 991 return -ECONNABORTED; 991 992 992 - pSMB->AndXCommand = 0xFF; /* none */ 993 + pSMB->AndXCommand = 0xFF; /* none */ 993 994 pSMB->Fid = netfid; 994 995 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 995 996 if(wct == 12) 996 997 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 997 - else if((lseek >> 32) > 0) /* can not handle this big offset for old */ 998 - return -EIO; 998 + else if((lseek >> 32) > 0) /* can not handle this big offset for old */ 999 + return -EIO; 999 1000 1000 1001 pSMB->Remaining = 0; 1001 1002 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); ··· 1004 1005 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1005 1006 else { 1006 1007 /* old style read */ 1007 - struct smb_com_readx_req * pSMBW = 1008 + struct smb_com_readx_req * pSMBW = 1008 1009 (struct smb_com_readx_req *)pSMB; 1009 - pSMBW->ByteCount = 0; 1010 + pSMBW->ByteCount = 0; 1010 1011 } 1011 - 1012 - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1013 - (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1012 + 1013 + iov[0].iov_base = (char *)pSMB; 1014 + iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1015 + rc = SendReceive2(xid, tcon->ses, iov, 1016 + 1 /* num iovecs */, 1017 + &resp_buf_type, 0); 1014 1018 cifs_stats_inc(&tcon->num_reads); 1019 + pSMBr = (READ_RSP *)iov[0].iov_base; 1015 1020 if (rc) { 1016 1021 cERROR(1, ("Send error in read = %d", rc)); 1017 1022 } else { ··· 1025 1022 *nbytes = data_length; 1026 1023 1027 1024 /*check that DataLength would not go beyond end of SMB */ 1028 - if ((data_length > CIFSMaxBufSize) 1025 + if ((data_length > CIFSMaxBufSize) 1029 1026 || (data_length > count)) { 1030 1027 cFYI(1,("bad length %d for count %d",data_length,count)); 1031 1028 rc = -EIO; 1032 1029 *nbytes = 0; 1033 1030 } else { 1034 - pReadData = 1035 - (char *) (&pSMBr->hdr.Protocol) + 1031 + pReadData = (char *) (&pSMBr->hdr.Protocol) + 1036 1032 le16_to_cpu(pSMBr->DataOffset); 1037 - /* if(rc = copy_to_user(buf, pReadData, data_length)) { 1038 - cERROR(1,("Faulting on read rc = %d",rc)); 1039 - rc = -EFAULT; 1040 - }*/ /* can not use copy_to_user when using page cache*/ 1033 + /* if(rc = copy_to_user(buf, pReadData, data_length)) { 1034 + cERROR(1,("Faulting on read rc = %d",rc)); 1035 + rc = -EFAULT; 1036 + }*/ /* can not use copy_to_user when using page cache*/ 1041 1037 if(*buf) 1042 - memcpy(*buf,pReadData,data_length); 1038 + memcpy(*buf,pReadData,data_length); 1043 1039 } 1044 1040 } 1045 - if(*buf) 1046 - cifs_buf_release(pSMB); 1047 - else 1048 - *buf = (char *)pSMB; 1049 1041 1050 - /* Note: On -EAGAIN error only caller can retry on handle based calls 1042 + cifs_small_buf_release(pSMB); 1043 + if(*buf) { 1044 + if(resp_buf_type == CIFS_SMALL_BUFFER) 1045 + cifs_small_buf_release(iov[0].iov_base); 1046 + else if(resp_buf_type == CIFS_LARGE_BUFFER) 1047 + cifs_buf_release(iov[0].iov_base); 1048 + } else /* return buffer to caller to free */ /* BB FIXME how do we tell caller if it is not a large buffer */ { 1049 + *buf = iov[0].iov_base; 1050 + if(resp_buf_type == CIFS_SMALL_BUFFER) 1051 + *pbuf_type = CIFS_SMALL_BUFFER; 1052 + else if(resp_buf_type == CIFS_LARGE_BUFFER) 1053 + *pbuf_type = CIFS_LARGE_BUFFER; 1054 + } 1055 + 1056 + /* Note: On -EAGAIN error only caller can retry on handle based calls 1051 1057 since file handle passed in no longer valid */ 1052 1058 return rc; 1053 1059 } 1060 + 1054 1061 1055 1062 int 1056 1063 CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, ··· 1168 1155 return rc; 1169 1156 } 1170 1157 1171 - #ifdef CONFIG_CIFS_EXPERIMENTAL 1172 1158 int 1173 1159 CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 1174 1160 const int netfid, const unsigned int count, ··· 1176 1164 { 1177 1165 int rc = -EACCES; 1178 1166 WRITE_REQ *pSMB = NULL; 1179 - int bytes_returned, wct; 1167 + int wct; 1180 1168 int smb_hdr_len; 1169 + int resp_buf_type = 0; 1181 1170 1182 - /* BB removeme BB */ 1183 1171 cFYI(1,("write2 at %lld %d bytes", (long long)offset, count)); 1184 1172 1185 1173 if(tcon->ses->capabilities & CAP_LARGE_FILES) ··· 1222 1210 pSMBW->ByteCount = cpu_to_le16(count + 5); 1223 1211 } 1224 1212 iov[0].iov_base = pSMB; 1225 - iov[0].iov_len = smb_hdr_len + 4; 1213 + if(wct == 14) 1214 + iov[0].iov_len = smb_hdr_len + 4; 1215 + else /* wct == 12 pad bigger by four bytes */ 1216 + iov[0].iov_len = smb_hdr_len + 8; 1217 + 1226 1218 1227 - rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned, 1219 + rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 1228 1220 long_op); 1229 1221 cifs_stats_inc(&tcon->num_writes); 1230 1222 if (rc) { 1231 1223 cFYI(1, ("Send error Write2 = %d", rc)); 1232 1224 *nbytes = 0; 1225 + } else if(resp_buf_type == 0) { 1226 + /* presumably this can not happen, but best to be safe */ 1227 + rc = -EIO; 1228 + *nbytes = 0; 1233 1229 } else { 1234 - WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB; 1230 + WRITE_RSP * pSMBr = (WRITE_RSP *)iov[0].iov_base; 1235 1231 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1236 1232 *nbytes = (*nbytes) << 16; 1237 1233 *nbytes += le16_to_cpu(pSMBr->Count); 1238 - } 1234 + } 1239 1235 1240 1236 cifs_small_buf_release(pSMB); 1237 + if(resp_buf_type == CIFS_SMALL_BUFFER) 1238 + cifs_small_buf_release(iov[0].iov_base); 1239 + else if(resp_buf_type == CIFS_LARGE_BUFFER) 1240 + cifs_buf_release(iov[0].iov_base); 1241 1241 1242 1242 /* Note: On -EAGAIN error only caller can retry on handle based calls 1243 1243 since file handle passed in no longer valid */ ··· 1257 1233 return rc; 1258 1234 } 1259 1235 1260 - 1261 - #endif /* CIFS_EXPERIMENTAL */ 1262 1236 1263 1237 int 1264 1238 CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ··· 1928 1906 return rc; 1929 1907 } 1930 1908 1909 + /* Initialize NT TRANSACT SMB into small smb request buffer. 1910 + This assumes that all NT TRANSACTS that we init here have 1911 + total parm and data under about 400 bytes (to fit in small cifs 1912 + buffer size), which is the case so far, it easily fits. NB: 1913 + Setup words themselves and ByteCount 1914 + MaxSetupCount (size of returned setup area) and 1915 + MaxParameterCount (returned parms size) must be set by caller */ 1916 + static int 1917 + smb_init_ntransact(const __u16 sub_command, const int setup_count, 1918 + const int parm_len, struct cifsTconInfo *tcon, 1919 + void ** ret_buf) 1920 + { 1921 + int rc; 1922 + __u32 temp_offset; 1923 + struct smb_com_ntransact_req * pSMB; 1924 + 1925 + rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 1926 + (void **)&pSMB); 1927 + if (rc) 1928 + return rc; 1929 + *ret_buf = (void *)pSMB; 1930 + pSMB->Reserved = 0; 1931 + pSMB->TotalParameterCount = cpu_to_le32(parm_len); 1932 + pSMB->TotalDataCount = 0; 1933 + pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - 1934 + MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); 1935 + pSMB->ParameterCount = pSMB->TotalParameterCount; 1936 + pSMB->DataCount = pSMB->TotalDataCount; 1937 + temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + 1938 + (setup_count * 2) - 4 /* for rfc1001 length itself */; 1939 + pSMB->ParameterOffset = cpu_to_le32(temp_offset); 1940 + pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); 1941 + pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ 1942 + pSMB->SubCommand = cpu_to_le16(sub_command); 1943 + return 0; 1944 + } 1945 + 1946 + static int 1947 + validate_ntransact(char * buf, char ** ppparm, char ** ppdata, 1948 + int * pdatalen, int * pparmlen) 1949 + { 1950 + char * end_of_smb; 1951 + __u32 data_count, data_offset, parm_count, parm_offset; 1952 + struct smb_com_ntransact_rsp * pSMBr; 1953 + 1954 + if(buf == NULL) 1955 + return -EINVAL; 1956 + 1957 + pSMBr = (struct smb_com_ntransact_rsp *)buf; 1958 + 1959 + /* ByteCount was converted from little endian in SendReceive */ 1960 + end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + 1961 + (char *)&pSMBr->ByteCount; 1962 + 1963 + 1964 + data_offset = le32_to_cpu(pSMBr->DataOffset); 1965 + data_count = le32_to_cpu(pSMBr->DataCount); 1966 + parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 1967 + parm_count = le32_to_cpu(pSMBr->ParameterCount); 1968 + 1969 + *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; 1970 + *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; 1971 + 1972 + /* should we also check that parm and data areas do not overlap? */ 1973 + if(*ppparm > end_of_smb) { 1974 + cFYI(1,("parms start after end of smb")); 1975 + return -EINVAL; 1976 + } else if(parm_count + *ppparm > end_of_smb) { 1977 + cFYI(1,("parm end after end of smb")); 1978 + return -EINVAL; 1979 + } else if(*ppdata > end_of_smb) { 1980 + cFYI(1,("data starts after end of smb")); 1981 + return -EINVAL; 1982 + } else if(data_count + *ppdata > end_of_smb) { 1983 + cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p", 1984 + *ppdata, data_count, (data_count + *ppdata), end_of_smb, pSMBr)); /* BB FIXME */ 1985 + return -EINVAL; 1986 + } else if(parm_count + data_count > pSMBr->ByteCount) { 1987 + cFYI(1,("parm count and data count larger than SMB")); 1988 + return -EINVAL; 1989 + } 1990 + return 0; 1991 + } 1992 + 1931 1993 int 1932 1994 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 1933 1995 const unsigned char *searchName, ··· 2034 1928 pSMB->TotalDataCount = 0; 2035 1929 pSMB->MaxParameterCount = cpu_to_le32(2); 2036 1930 /* BB find exact data count max from sess structure BB */ 2037 - pSMB->MaxDataCount = cpu_to_le32(4000); 1931 + pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - 1932 + MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); 2038 1933 pSMB->MaxSetupCount = 4; 2039 1934 pSMB->Reserved = 0; 2040 1935 pSMB->ParameterOffset = 0; ··· 2062 1955 rc = -EIO; /* bad smb */ 2063 1956 else { 2064 1957 if(data_count && (data_count < 2048)) { 2065 - char * end_of_smb = pSMBr->ByteCount + (char *)&pSMBr->ByteCount; 1958 + char * end_of_smb = 2 /* sizeof byte count */ + 1959 + pSMBr->ByteCount + 1960 + (char *)&pSMBr->ByteCount; 2066 1961 2067 1962 struct reparse_data * reparse_buf = (struct reparse_data *) 2068 1963 ((char *)&pSMBr->hdr.Protocol + data_offset); ··· 2308 2199 2309 2200 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2310 2201 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2202 + cifs_stats_inc(&tcon->num_acl_get); 2311 2203 if (rc) { 2312 2204 cFYI(1, ("Send error in Query POSIX ACL = %d", rc)); 2313 2205 } else { ··· 2495 2385 2496 2386 2497 2387 #endif /* CONFIG_POSIX */ 2388 + 2389 + 2390 + /* security id for everyone */ 2391 + const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; 2392 + /* group users */ 2393 + const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 2394 + 2395 + /* Convert CIFS ACL to POSIX form */ 2396 + static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) 2397 + { 2398 + return 0; 2399 + } 2400 + 2401 + /* Get Security Descriptor (by handle) from remote server for a file or dir */ 2402 + int 2403 + CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 2404 + /* BB fix up return info */ char *acl_inf, const int buflen, 2405 + const int acl_type /* ACCESS/DEFAULT not sure implication */) 2406 + { 2407 + int rc = 0; 2408 + int buf_type = 0; 2409 + QUERY_SEC_DESC_REQ * pSMB; 2410 + struct kvec iov[1]; 2411 + 2412 + cFYI(1, ("GetCifsACL")); 2413 + 2414 + rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 2415 + 8 /* parm len */, tcon, (void **) &pSMB); 2416 + if (rc) 2417 + return rc; 2418 + 2419 + pSMB->MaxParameterCount = cpu_to_le32(4); 2420 + /* BB TEST with big acls that might need to be e.g. larger than 16K */ 2421 + pSMB->MaxSetupCount = 0; 2422 + pSMB->Fid = fid; /* file handle always le */ 2423 + pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | 2424 + CIFS_ACL_DACL); 2425 + pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 2426 + pSMB->hdr.smb_buf_length += 11; 2427 + iov[0].iov_base = (char *)pSMB; 2428 + iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 2429 + 2430 + rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0); 2431 + cifs_stats_inc(&tcon->num_acl_get); 2432 + if (rc) { 2433 + cFYI(1, ("Send error in QuerySecDesc = %d", rc)); 2434 + } else { /* decode response */ 2435 + struct cifs_sid * psec_desc; 2436 + __le32 * parm; 2437 + int parm_len; 2438 + int data_len; 2439 + int acl_len; 2440 + struct smb_com_ntransact_rsp * pSMBr; 2441 + 2442 + /* validate_nttransact */ 2443 + rc = validate_ntransact(iov[0].iov_base, (char **)&parm, 2444 + (char **)&psec_desc, 2445 + &parm_len, &data_len); 2446 + 2447 + if(rc) 2448 + goto qsec_out; 2449 + pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; 2450 + 2451 + cERROR(1,("smb %p parm %p data %p",pSMBr,parm,psec_desc)); /* BB removeme BB */ 2452 + 2453 + if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 2454 + rc = -EIO; /* bad smb */ 2455 + goto qsec_out; 2456 + } 2457 + 2458 + /* BB check that data area is minimum length and as big as acl_len */ 2459 + 2460 + acl_len = le32_to_cpu(*(__le32 *)parm); 2461 + /* BB check if(acl_len > bufsize) */ 2462 + 2463 + parse_sec_desc(psec_desc, acl_len); 2464 + } 2465 + qsec_out: 2466 + if(buf_type == CIFS_SMALL_BUFFER) 2467 + cifs_small_buf_release(iov[0].iov_base); 2468 + else if(buf_type == CIFS_LARGE_BUFFER) 2469 + cifs_buf_release(iov[0].iov_base); 2470 + cifs_small_buf_release(pSMB); 2471 + return rc; 2472 + } 2473 + 2498 2474 2499 2475 /* Legacy Query Path Information call for lookup to old servers such 2500 2476 as Win9x/WinME */ ··· 4480 4284 { 4481 4285 int rc = 0; 4482 4286 struct smb_com_transaction_change_notify_req * pSMB = NULL; 4483 - struct smb_com_transaction_change_notify_rsp * pSMBr = NULL; 4287 + struct smb_com_ntransaction_change_notify_rsp * pSMBr = NULL; 4484 4288 struct dir_notify_req *dnotify_req; 4485 4289 int bytes_returned; 4486 4290 ··· 4495 4299 pSMB->MaxParameterCount = cpu_to_le32(2); 4496 4300 /* BB find exact data count max from sess structure BB */ 4497 4301 pSMB->MaxDataCount = 0; /* same in little endian or be */ 4302 + /* BB VERIFY verify which is correct for above BB */ 4303 + pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - 4304 + MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); 4305 + 4498 4306 pSMB->MaxSetupCount = 4; 4499 4307 pSMB->Reserved = 0; 4500 4308 pSMB->ParameterOffset = 0;
+76 -13
fs/cifs/connect.c
··· 76 76 unsigned setuids:1; 77 77 unsigned noperm:1; 78 78 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ 79 + unsigned cifs_acl:1; 79 80 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ 80 81 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ 81 82 unsigned direct_io:1; 82 83 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 83 84 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ 84 85 unsigned sfu_emul:1; 86 + unsigned krb5:1; 87 + unsigned ntlm:1; 88 + unsigned ntlmv2:1; 89 + unsigned nullauth:1; /* attempt to authenticate with null user */ 90 + unsigned sign:1; 91 + unsigned seal:1; /* encrypt */ 85 92 unsigned nocase; /* request case insensitive filenames */ 86 93 unsigned nobrl; /* disable sending byte range locks to srv */ 87 94 unsigned int rsize; ··· 515 508 /* else length ok */ 516 509 reconnect = 0; 517 510 518 - if(pdu_length > MAX_CIFS_HDR_SIZE - 4) { 511 + if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { 519 512 isLargeBuf = TRUE; 520 513 memcpy(bigbuf, smallbuf, 4); 521 514 smb_buffer = bigbuf; ··· 784 777 785 778 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ 786 779 vol->rw = TRUE; 787 - 780 + vol->ntlm = TRUE; 788 781 /* default is always to request posix paths. */ 789 782 vol->posix_paths = 1; 790 783 ··· 910 903 printk(KERN_WARNING "CIFS: ip address too long\n"); 911 904 return 1; 912 905 } 906 + } else if (strnicmp(data, "sec", 3) == 0) { 907 + if (!value || !*value) { 908 + cERROR(1,("no security value specified")); 909 + continue; 910 + } else if (strnicmp(value, "krb5i", 5) == 0) { 911 + vol->sign = 1; 912 + vol->krb5 = 1; 913 + } else if (strnicmp(value, "krb5p", 5) == 0) { 914 + /* vol->seal = 1; 915 + vol->krb5 = 1; */ 916 + cERROR(1,("Krb5 cifs privacy not supported")); 917 + return 1; 918 + } else if (strnicmp(value, "krb5", 4) == 0) { 919 + vol->krb5 = 1; 920 + } else if (strnicmp(value, "ntlmv2i", 7) == 0) { 921 + vol->ntlmv2 = 1; 922 + vol->sign = 1; 923 + } else if (strnicmp(value, "ntlmv2", 6) == 0) { 924 + vol->ntlmv2 = 1; 925 + } else if (strnicmp(value, "ntlmi", 5) == 0) { 926 + vol->ntlm = 1; 927 + vol->sign = 1; 928 + } else if (strnicmp(value, "ntlm", 4) == 0) { 929 + /* ntlm is default so can be turned off too */ 930 + vol->ntlm = 1; 931 + } else if (strnicmp(value, "nontlm", 6) == 0) { 932 + vol->ntlm = 0; 933 + } else if (strnicmp(value, "none", 4) == 0) { 934 + vol->nullauth = 1; 935 + } else { 936 + cERROR(1,("bad security option: %s", value)); 937 + return 1; 938 + } 913 939 } else if ((strnicmp(data, "unc", 3) == 0) 914 940 || (strnicmp(data, "target", 6) == 0) 915 941 || (strnicmp(data, "path", 4) == 0)) { ··· 1160 1120 vol->server_ino = 1; 1161 1121 } else if (strnicmp(data, "noserverino",9) == 0) { 1162 1122 vol->server_ino = 0; 1123 + } else if (strnicmp(data, "cifsacl",7) == 0) { 1124 + vol->cifs_acl = 1; 1125 + } else if (strnicmp(data, "nocifsacl", 9) == 0) { 1126 + vol->cifs_acl = 0; 1163 1127 } else if (strnicmp(data, "acl",3) == 0) { 1164 1128 vol->no_psx_acl = 0; 1165 1129 } else if (strnicmp(data, "noacl",5) == 0) { ··· 1590 1546 cFYI(1, ("Username: %s ", volume_info.username)); 1591 1547 1592 1548 } else { 1593 - cifserror("No username specified "); 1549 + cifserror("No username specified"); 1594 1550 /* In userspace mount helper we can get user name from alternate 1595 1551 locations such as env variables and files on disk */ 1596 1552 kfree(volume_info.UNC); ··· 1631 1587 return -EINVAL; 1632 1588 } else /* which servers DFS root would we conect to */ { 1633 1589 cERROR(1, 1634 - ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); 1590 + ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); 1635 1591 kfree(volume_info.UNC); 1636 1592 kfree(volume_info.password); 1637 1593 FreeXid(xid); ··· 1670 1626 1671 1627 1672 1628 if (srvTcp) { 1673 - cFYI(1, ("Existing tcp session with server found ")); 1629 + cFYI(1, ("Existing tcp session with server found")); 1674 1630 } else { /* create socket */ 1675 1631 if(volume_info.port) 1676 1632 sin_server.sin_port = htons(volume_info.port); ··· 1733 1689 1734 1690 if (existingCifsSes) { 1735 1691 pSesInfo = existingCifsSes; 1736 - cFYI(1, ("Existing smb sess found ")); 1692 + cFYI(1, ("Existing smb sess found")); 1737 1693 kfree(volume_info.password); 1738 1694 /* volume_info.UNC freed at end of function */ 1739 1695 } else if (!rc) { 1740 - cFYI(1, ("Existing smb sess not found ")); 1696 + cFYI(1, ("Existing smb sess not found")); 1741 1697 pSesInfo = sesInfoAlloc(); 1742 1698 if (pSesInfo == NULL) 1743 1699 rc = -ENOMEM; ··· 1795 1751 cifs_sb->mnt_gid = volume_info.linux_gid; 1796 1752 cifs_sb->mnt_file_mode = volume_info.file_mode; 1797 1753 cifs_sb->mnt_dir_mode = volume_info.dir_mode; 1798 - cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); 1754 + cFYI(1,("file mode: 0x%x dir mode: 0x%x", 1755 + cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); 1799 1756 1800 1757 if(volume_info.noperm) 1801 1758 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; ··· 1812 1767 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; 1813 1768 if(volume_info.nobrl) 1814 1769 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; 1770 + if(volume_info.cifs_acl) 1771 + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 1815 1772 1816 1773 if(volume_info.direct_io) { 1817 1774 cFYI(1,("mounting share using direct i/o")); ··· 1824 1777 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, 1825 1778 volume_info.username); 1826 1779 if (tcon) { 1827 - cFYI(1, ("Found match on UNC path ")); 1780 + cFYI(1, ("Found match on UNC path")); 1828 1781 /* we can have only one retry value for a connection 1829 1782 to a share so for resources mounted more than once 1830 1783 to the same server share the last value passed in ··· 1973 1926 __u32 capabilities; 1974 1927 __u16 count; 1975 1928 1976 - cFYI(1, ("In sesssetup ")); 1929 + cFYI(1, ("In sesssetup")); 1977 1930 if(ses == NULL) 1978 1931 return -EINVAL; 1979 1932 user = ses->userName; ··· 3249 3202 3250 3203 pSMB->AndXCommand = 0xFF; 3251 3204 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); 3252 - pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 3253 3205 bcc_ptr = &pSMB->Password[0]; 3254 - bcc_ptr++; /* skip password */ 3206 + if((ses->server->secMode) & SECMODE_USER) { 3207 + pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 3208 + bcc_ptr++; /* skip password */ 3209 + } else { 3210 + pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE); 3211 + /* BB FIXME add code to fail this if NTLMv2 or Kerberos 3212 + specified as required (when that support is added to 3213 + the vfs in the future) as only NTLM or the much 3214 + weaker LANMAN (which we do not send) is accepted 3215 + by Samba (not sure whether other servers allow 3216 + NTLMv2 password here) */ 3217 + SMBNTencrypt(ses->password, 3218 + ses->server->cryptKey, 3219 + bcc_ptr); 3220 + 3221 + bcc_ptr += CIFS_SESSION_KEY_SIZE; 3222 + *bcc_ptr = 0; 3223 + bcc_ptr++; /* align */ 3224 + } 3255 3225 3256 3226 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3257 3227 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; ··· 3286 3222 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ 3287 3223 bcc_ptr += 2; /* skip trailing null */ 3288 3224 } else { /* ASCII */ 3289 - 3290 3225 strcpy(bcc_ptr, tree); 3291 3226 bcc_ptr += strlen(tree) + 1; 3292 3227 }
+4 -4
fs/cifs/dir.c
··· 3 3 * 4 4 * vfs operations that deal with dentries 5 5 * 6 - * Copyright (C) International Business Machines Corp., 2002,2003 6 + * Copyright (C) International Business Machines Corp., 2002,2005 7 7 * Author(s): Steve French (sfrench@us.ibm.com) 8 8 * 9 9 * This library is free software; you can redistribute it and/or modify ··· 200 200 (oplock & CIFS_CREATE_ACTION)) 201 201 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 202 202 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 203 - (__u64)current->euid, 204 - (__u64)current->egid, 203 + (__u64)current->fsuid, 204 + (__u64)current->fsgid, 205 205 0 /* dev */, 206 206 cifs_sb->local_nls, 207 207 cifs_sb->mnt_cifs_flags & ··· 325 325 else if (pTcon->ses->capabilities & CAP_UNIX) { 326 326 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 327 327 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 328 - mode,(__u64)current->euid,(__u64)current->egid, 328 + mode,(__u64)current->fsuid,(__u64)current->fsgid, 329 329 device_number, cifs_sb->local_nls, 330 330 cifs_sb->mnt_cifs_flags & 331 331 CIFS_MOUNT_MAP_SPECIAL_CHR);
+46 -27
fs/cifs/file.c
··· 553 553 } 554 554 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; 555 555 if (ptmp) { 556 - /* BB removeme BB */ cFYI(1, ("freeing smb buf in srch struct in closedir")); 556 + cFYI(1, ("closedir free smb buf in srch struct")); 557 557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL; 558 558 cifs_buf_release(ptmp); 559 559 } 560 560 ptmp = pCFileStruct->search_resume_name; 561 561 if (ptmp) { 562 - /* BB removeme BB */ cFYI(1, ("freeing resume name in closedir")); 562 + cFYI(1, ("closedir free resume name")); 563 563 pCFileStruct->search_resume_name = NULL; 564 564 kfree(ptmp); 565 565 } ··· 868 868 if (rc != 0) 869 869 break; 870 870 } 871 - #ifdef CONFIG_CIFS_EXPERIMENTAL 872 871 /* BB FIXME We can not sign across two buffers yet */ 873 - if((experimEnabled) && ((pTcon->ses->server->secMode & 874 - (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) { 872 + if((pTcon->ses->server->secMode & 873 + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { 875 874 struct kvec iov[2]; 876 875 unsigned int len; 877 876 ··· 886 887 iov, 1, long_op); 887 888 } else 888 889 /* BB FIXME fixup indentation of line below */ 889 - #endif 890 890 rc = CIFSSMBWrite(xid, pTcon, 891 891 open_file->netfid, 892 892 min_t(const int, cifs_sb->wsize, ··· 1022 1024 return rc; 1023 1025 } 1024 1026 1025 - #ifdef CONFIG_CIFS_EXPERIMENTAL 1026 1027 static int cifs_writepages(struct address_space *mapping, 1027 1028 struct writeback_control *wbc) 1028 1029 { ··· 1224 1227 1225 1228 return rc; 1226 1229 } 1227 - #endif 1228 1230 1229 1231 static int cifs_writepage(struct page* page, struct writeback_control *wbc) 1230 1232 { ··· 1422 1426 rc = -EAGAIN; 1423 1427 smb_read_data = NULL; 1424 1428 while (rc == -EAGAIN) { 1429 + int buf_type = CIFS_NO_BUFFER; 1425 1430 if ((open_file->invalidHandle) && 1426 1431 (!open_file->closePend)) { 1427 1432 rc = cifs_reopen_file(file->f_dentry->d_inode, ··· 1431 1434 break; 1432 1435 } 1433 1436 rc = CIFSSMBRead(xid, pTcon, 1434 - open_file->netfid, 1435 - current_read_size, *poffset, 1436 - &bytes_read, &smb_read_data); 1437 + open_file->netfid, 1438 + current_read_size, *poffset, 1439 + &bytes_read, &smb_read_data, 1440 + &buf_type); 1437 1441 pSMBr = (struct smb_com_read_rsp *)smb_read_data; 1438 1442 if (copy_to_user(current_offset, 1439 1443 smb_read_data + 4 /* RFC1001 hdr */ 1440 1444 + le16_to_cpu(pSMBr->DataOffset), 1441 1445 bytes_read)) { 1442 1446 rc = -EFAULT; 1443 - FreeXid(xid); 1444 - return rc; 1445 - } 1447 + } 1446 1448 if (smb_read_data) { 1447 - cifs_buf_release(smb_read_data); 1449 + if(buf_type == CIFS_SMALL_BUFFER) 1450 + cifs_small_buf_release(smb_read_data); 1451 + else if(buf_type == CIFS_LARGE_BUFFER) 1452 + cifs_buf_release(smb_read_data); 1448 1453 smb_read_data = NULL; 1449 1454 } 1450 1455 } ··· 1479 1480 int xid; 1480 1481 char *current_offset; 1481 1482 struct cifsFileInfo *open_file; 1483 + int buf_type = CIFS_NO_BUFFER; 1482 1484 1483 1485 xid = GetXid(); 1484 1486 cifs_sb = CIFS_SB(file->f_dentry->d_sb); ··· 1516 1516 break; 1517 1517 } 1518 1518 rc = CIFSSMBRead(xid, pTcon, 1519 - open_file->netfid, 1520 - current_read_size, *poffset, 1521 - &bytes_read, &current_offset); 1519 + open_file->netfid, 1520 + current_read_size, *poffset, 1521 + &bytes_read, &current_offset, 1522 + &buf_type); 1522 1523 } 1523 1524 if (rc || (bytes_read == 0)) { 1524 1525 if (total_read) { ··· 1617 1616 struct smb_com_read_rsp *pSMBr; 1618 1617 struct pagevec lru_pvec; 1619 1618 struct cifsFileInfo *open_file; 1619 + int buf_type = CIFS_NO_BUFFER; 1620 1620 1621 1621 xid = GetXid(); 1622 1622 if (file->private_data == NULL) { ··· 1674 1672 } 1675 1673 1676 1674 rc = CIFSSMBRead(xid, pTcon, 1677 - open_file->netfid, 1678 - read_size, offset, 1679 - &bytes_read, &smb_read_data); 1680 - 1675 + open_file->netfid, 1676 + read_size, offset, 1677 + &bytes_read, &smb_read_data, 1678 + &buf_type); 1681 1679 /* BB more RC checks ? */ 1682 1680 if (rc== -EAGAIN) { 1683 1681 if (smb_read_data) { 1684 - cifs_buf_release(smb_read_data); 1682 + if(buf_type == CIFS_SMALL_BUFFER) 1683 + cifs_small_buf_release(smb_read_data); 1684 + else if(buf_type == CIFS_LARGE_BUFFER) 1685 + cifs_buf_release(smb_read_data); 1685 1686 smb_read_data = NULL; 1686 1687 } 1687 1688 } ··· 1741 1736 break; 1742 1737 } 1743 1738 if (smb_read_data) { 1744 - cifs_buf_release(smb_read_data); 1739 + if(buf_type == CIFS_SMALL_BUFFER) 1740 + cifs_small_buf_release(smb_read_data); 1741 + else if(buf_type == CIFS_LARGE_BUFFER) 1742 + cifs_buf_release(smb_read_data); 1745 1743 smb_read_data = NULL; 1746 1744 } 1747 1745 bytes_read = 0; ··· 1754 1746 1755 1747 /* need to free smb_read_data buf before exit */ 1756 1748 if (smb_read_data) { 1757 - cifs_buf_release(smb_read_data); 1749 + if(buf_type == CIFS_SMALL_BUFFER) 1750 + cifs_small_buf_release(smb_read_data); 1751 + else if(buf_type == CIFS_LARGE_BUFFER) 1752 + cifs_buf_release(smb_read_data); 1758 1753 smb_read_data = NULL; 1759 1754 } 1760 1755 ··· 1836 1825 open_file = find_writable_file(cifsInode); 1837 1826 1838 1827 if(open_file) { 1828 + struct cifs_sb_info *cifs_sb; 1829 + 1839 1830 /* there is not actually a write pending so let 1840 1831 this handle go free and allow it to 1841 1832 be closable if needed */ 1842 1833 atomic_dec(&open_file->wrtPending); 1834 + 1835 + cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); 1836 + if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { 1837 + /* since no page cache to corrupt on directio 1838 + we can change size safely */ 1839 + return 1; 1840 + } 1841 + 1843 1842 return 0; 1844 1843 } else 1845 1844 return 1; ··· 1894 1873 .readpage = cifs_readpage, 1895 1874 .readpages = cifs_readpages, 1896 1875 .writepage = cifs_writepage, 1897 - #ifdef CONFIG_CIFS_EXPERIMENTAL 1898 1876 .writepages = cifs_writepages, 1899 - #endif 1900 1877 .prepare_write = cifs_prepare_write, 1901 1878 .commit_write = cifs_commit_write, 1902 1879 .set_page_dirty = __set_page_dirty_nobuffers,
+5 -4
fs/cifs/inode.c
··· 229 229 cifs_sb->mnt_cifs_flags & 230 230 CIFS_MOUNT_MAP_SPECIAL_CHR); 231 231 if (rc==0) { 232 + int buf_type = CIFS_NO_BUFFER; 232 233 /* Read header */ 233 234 rc = CIFSSMBRead(xid, pTcon, 234 235 netfid, 235 236 24 /* length */, 0 /* offset */, 236 - &bytes_read, &pbuf); 237 + &bytes_read, &pbuf, &buf_type); 237 238 if((rc == 0) && (bytes_read >= 8)) { 238 239 if(memcmp("IntxBLK", pbuf, 8) == 0) { 239 240 cFYI(1,("Block device")); ··· 268 267 } else { 269 268 inode->i_mode |= S_IFREG; /* then it is a file */ 270 269 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 271 - } 270 + } 272 271 CIFSSMBClose(xid, pTcon, netfid); 273 272 } 274 273 return rc; ··· 751 750 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 752 751 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 753 752 mode, 754 - (__u64)current->euid, 755 - (__u64)current->egid, 753 + (__u64)current->fsuid, 754 + (__u64)current->fsgid, 756 755 0 /* dev_t */, 757 756 cifs_sb->local_nls, 758 757 cifs_sb->mnt_cifs_flags &
+12 -5
fs/cifs/misc.c
··· 1 1 /* 2 2 * fs/cifs/misc.c 3 3 * 4 - * Copyright (C) International Business Machines Corp., 2002,2004 4 + * Copyright (C) International Business Machines Corp., 2002,2005 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 161 161 if (ret_buf) { 162 162 memset(ret_buf, 0, sizeof(struct smb_hdr) + 3); 163 163 atomic_inc(&bufAllocCount); 164 + #ifdef CONFIG_CIFS_STATS2 165 + atomic_inc(&totBufAllocCount); 166 + #endif /* CONFIG_CIFS_STATS2 */ 164 167 } 165 168 166 169 return ret_buf; ··· 198 195 /* No need to clear memory here, cleared in header assemble */ 199 196 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ 200 197 atomic_inc(&smBufAllocCount); 198 + #ifdef CONFIG_CIFS_STATS2 199 + atomic_inc(&totSmBufAllocCount); 200 + #endif /* CONFIG_CIFS_STATS2 */ 201 + 201 202 } 202 203 return ret_buf; 203 204 } ··· 299 292 struct cifsSesInfo * ses; 300 293 char *temp = (char *) buffer; 301 294 302 - memset(temp,0,MAX_CIFS_HDR_SIZE); 295 + memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */ 303 296 304 297 buffer->smb_buf_length = 305 298 (2 * word_count) + sizeof (struct smb_hdr) - ··· 355 348 /* BB Add support for establishing new tCon and SMB Session */ 356 349 /* with userid/password pairs found on the smb session */ 357 350 /* for other target tcp/ip addresses BB */ 358 - if(current->uid != treeCon->ses->linux_uid) { 359 - cFYI(1,("Multiuser mode and UID did not match tcon uid ")); 351 + if(current->fsuid != treeCon->ses->linux_uid) { 352 + cFYI(1,("Multiuser mode and UID did not match tcon uid")); 360 353 read_lock(&GlobalSMBSeslock); 361 354 list_for_each(temp_item, &GlobalSMBSessionList) { 362 355 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); 363 - if(ses->linux_uid == current->uid) { 356 + if(ses->linux_uid == current->fsuid) { 364 357 if(ses->server == treeCon->ses->server) { 365 358 cFYI(1,("found matching uid substitute right smb_uid")); 366 359 buffer->Uid = ses->Suid;
+11 -6
fs/cifs/readdir.c
··· 214 214 tmp_inode->i_fop = &cifs_file_nobrl_ops; 215 215 else 216 216 tmp_inode->i_fop = &cifs_file_ops; 217 - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 218 - tmp_inode->i_fop->lock = NULL; 217 + 219 218 tmp_inode->i_data.a_ops = &cifs_addr_ops; 220 219 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 221 220 (cifs_sb->tcon->ses->server->maxBuf < ··· 326 327 if (S_ISREG(tmp_inode->i_mode)) { 327 328 cFYI(1, ("File inode")); 328 329 tmp_inode->i_op = &cifs_file_inode_ops; 329 - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 330 - tmp_inode->i_fop = &cifs_file_direct_ops; 330 + 331 + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 332 + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 333 + tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 334 + else 335 + tmp_inode->i_fop = &cifs_file_direct_ops; 336 + 337 + } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 338 + tmp_inode->i_fop = &cifs_file_nobrl_ops; 331 339 else 332 340 tmp_inode->i_fop = &cifs_file_ops; 333 - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 334 - tmp_inode->i_fop->lock = NULL; 341 + 335 342 tmp_inode->i_data.a_ops = &cifs_addr_ops; 336 343 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 337 344 (cifs_sb->tcon->ses->server->maxBuf <
+2 -2
fs/cifs/rfc1002pdu.h
··· 24 24 /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ 25 25 26 26 /* RFC 1002 session packet types */ 27 - #define RFC1002_SESSION_MESASAGE 0x00 27 + #define RFC1002_SESSION_MESSAGE 0x00 28 28 #define RFC1002_SESSION_REQUEST 0x81 29 29 #define RFC1002_POSITIVE_SESSION_RESPONSE 0x82 30 30 #define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83 31 - #define RFC1002_RETARGET_SESSION_RESPONSE 0x83 31 + #define RFC1002_RETARGET_SESSION_RESPONSE 0x84 32 32 #define RFC1002_SESSION_KEEP_ALIVE 0x85 33 33 34 34 /* RFC 1002 flags (only one defined */
+21 -19
fs/cifs/transport.c
··· 206 206 return rc; 207 207 } 208 208 209 - #ifdef CONFIG_CIFS_EXPERIMENTAL 210 209 static int 211 210 smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, 212 211 struct sockaddr *sin) ··· 298 299 299 300 int 300 301 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 301 - struct kvec *iov, int n_vec, int *pbytes_returned, 302 + struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 302 303 const int long_op) 303 304 { 304 305 int rc = 0; ··· 306 307 unsigned long timeout; 307 308 struct mid_q_entry *midQ; 308 309 struct smb_hdr *in_buf = iov[0].iov_base; 310 + 311 + *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 309 312 310 313 if (ses == NULL) { 311 314 cERROR(1,("Null smb session")); ··· 393 392 return -ENOMEM; 394 393 } 395 394 396 - /* BB FIXME */ 397 - /* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */ 395 + rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); 398 396 399 397 midQ->midState = MID_REQUEST_SUBMITTED; 400 398 #ifdef CONFIG_CIFS_STATS2 ··· 489 489 receive_len, xid)); 490 490 rc = -EIO; 491 491 } else { /* rcvd frame is ok */ 492 - 493 492 if (midQ->resp_buf && 494 493 (midQ->midState == MID_RESPONSE_RECEIVED)) { 495 - in_buf->smb_buf_length = receive_len; 496 - /* BB verify that length would not overrun small buf */ 497 - memcpy((char *)in_buf + 4, 498 - (char *)midQ->resp_buf + 4, 499 - receive_len); 500 494 501 - dump_smb(in_buf, 80); 495 + iov[0].iov_base = (char *)midQ->resp_buf; 496 + if(midQ->largeBuf) 497 + *pRespBufType = CIFS_LARGE_BUFFER; 498 + else 499 + *pRespBufType = CIFS_SMALL_BUFFER; 500 + iov[0].iov_len = receive_len + 4; 501 + iov[1].iov_len = 0; 502 + 503 + dump_smb(midQ->resp_buf, 80); 502 504 /* convert the length into a more usable form */ 503 505 if((receive_len > 24) && 504 506 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 505 507 SECMODE_SIGN_ENABLED))) { 506 - rc = cifs_verify_signature(in_buf, 508 + rc = cifs_verify_signature(midQ->resp_buf, 507 509 ses->server->mac_signing_key, 508 510 midQ->sequence_number+1); 509 511 if(rc) { ··· 514 512 } 515 513 } 516 514 517 - *pbytes_returned = in_buf->smb_buf_length; 518 - 519 515 /* BB special case reconnect tid and uid here? */ 520 516 /* BB special case Errbadpassword and pwdexpired here */ 521 - rc = map_smb_to_linux_error(in_buf); 517 + rc = map_smb_to_linux_error(midQ->resp_buf); 522 518 523 519 /* convert ByteCount if necessary */ 524 520 if (receive_len >= 525 521 sizeof (struct smb_hdr) - 526 522 4 /* do not count RFC1001 header */ + 527 - (2 * in_buf->WordCount) + 2 /* bcc */ ) 528 - BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf)); 523 + (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) 524 + BCC(midQ->resp_buf) = 525 + le16_to_cpu(BCC_LE(midQ->resp_buf)); 526 + midQ->resp_buf = NULL; /* mark it so will not be freed 527 + by DeleteMidQEntry */ 529 528 } else { 530 529 rc = -EIO; 531 530 cFYI(1,("Bad MID state?")); ··· 552 549 553 550 return rc; 554 551 } 555 - #endif /* CIFS_EXPERIMENTAL */ 556 552 557 553 int 558 554 SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ··· 792 790 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 793 791 } else { 794 792 rc = -EIO; 795 - cERROR(1,("Bad MID state? ")); 793 + cERROR(1,("Bad MID state?")); 796 794 } 797 795 } 798 796 cifs_no_response_exit:
+20 -2
fs/cifs/xattr.c
··· 254 254 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, 255 255 buf_size, cifs_sb->local_nls, 256 256 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 257 - } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { 257 + } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, 258 + strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { 258 259 #ifdef CONFIG_CIFS_POSIX 259 260 if(sb->s_flags & MS_POSIXACL) 260 261 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, ··· 263 262 cifs_sb->local_nls, 264 263 cifs_sb->mnt_cifs_flags & 265 264 CIFS_MOUNT_MAP_SPECIAL_CHR); 265 + /* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 266 + __u16 fid; 267 + int oplock = FALSE; 268 + rc = CIFSSMBOpen(xid, pTcon, full_path, 269 + FILE_OPEN, GENERIC_READ, 0, &fid, 270 + &oplock, NULL, cifs_sb->local_nls, 271 + cifs_sb->mnt_cifs_flags & 272 + CIFS_MOUNT_MAP_SPECIAL_CHR); 273 + if(rc == 0) { 274 + rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, 275 + ea_value, buf_size, 276 + ACL_TYPE_ACCESS); 277 + CIFSSMBClose(xid, pTcon, fid) 278 + } 279 + } */ /* BB enable after fixing up return data */ 280 + 266 281 #else 267 282 cFYI(1,("query POSIX ACL not supported yet")); 268 283 #endif /* CONFIG_CIFS_POSIX */ 269 - } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 284 + } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT, 285 + strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 270 286 #ifdef CONFIG_CIFS_POSIX 271 287 if(sb->s_flags & MS_POSIXACL) 272 288 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,