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: (27 commits)
[CIFS] Missing flags2 for DFS
[CIFS] Workaround incomplete byte length returned by some
[CIFS] cifs Kconfig: don't select CONNECTOR
[CIFS] Level 1 QPathInfo needed for proper OS2 support
[CIFS] fix typo in previous patch
[CIFS] Fix old DOS time conversion to handle timezone
[CIFS] Do not need to adjust for Jan/Feb for leap day
[CIFS] Fix leaps year calculation for years after 2100
[CIFS] readdir (ffirst) enablement of accurate timestamps from legacy servers
[CIFS] Fix compiler warning with previous patch
[CIFS] Fix typo
[CIFS] Allow for 15 minute TZs (e.g. Nepal) and be more explicit about
[CIFS] Fix readdir of large directories for backlevel servers
[CIFS] Allow LANMAN21 support even in both POSIX non-POSIX path
[CIFS] Make use of newer QFSInfo dependent on capability bit instead of
[CIFS] Do not send newer QFSInfo to legacy servers which can not support it
[CIFS] Fix typo in name of new cifs_show_stats
[CIFS] Rename server time zone field
[CIFS] Handle legacy servers which return undefined time zone
[CIFS] CIFS support for /proc/<pid>/mountstats part 1
...

Manual conflict resolution in fs/cifs/connect.c

+312 -98
+1 -1
fs/Kconfig
··· 1986 config CIFS_UPCALL 1987 bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" 1988 depends on CIFS_EXPERIMENTAL 1989 - select CONNECTOR 1990 help 1991 Enables an upcall mechanism for CIFS which will be used to contact 1992 userspace helper utilities to provide SPNEGO packaged Kerberos
··· 1986 config CIFS_UPCALL 1987 bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" 1988 depends on CIFS_EXPERIMENTAL 1989 + depends on CONNECTOR 1990 help 1991 Enables an upcall mechanism for CIFS which will be used to contact 1992 userspace helper utilities to provide SPNEGO packaged Kerberos
+2 -2
fs/cifs/cifsacl.h
··· 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 */
··· 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 */
-2
fs/cifs/cifsencrypt.h
··· 27 /* smbdes.c */ 28 extern void E_P16(unsigned char *p14, unsigned char *p16); 29 extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); 30 - extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); 31 - extern void E_old_pw_hash(unsigned char *, unsigned char *, unsigned char *); 32 33 34
··· 27 /* smbdes.c */ 28 extern void E_P16(unsigned char *p14, unsigned char *p16); 29 extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); 30 31 32
+21 -6
fs/cifs/cifsfs.c
··· 63 struct task_struct * oplockThread = NULL; 64 extern struct task_struct * dnotifyThread; /* remove sparse warning */ 65 struct task_struct * dnotifyThread = NULL; 66 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 67 module_param(CIFSMaxBufSize, int, 0); 68 MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); ··· 199 /* Only need to call the old QFSInfo if failed 200 on newer one */ 201 if(rc) 202 - rc = CIFSSMBQFSInfo(xid, pTcon, buf); 203 204 - /* Old Windows servers do not support level 103, retry with level 205 - one if old server failed the previous call */ 206 if(rc) 207 rc = SMBOldQFSInfo(xid, pTcon, buf); 208 /* ··· 438 return; 439 } 440 441 static int cifs_remount(struct super_block *sb, int *flags, char *data) 442 { 443 *flags |= MS_NODIRATIME; 444 return 0; 445 } 446 447 - struct super_operations cifs_super_ops = { 448 .read_inode = cifs_read_inode, 449 .put_super = cifs_put_super, 450 .statfs = cifs_statfs, ··· 465 .show_options = cifs_show_options, 466 .umount_begin = cifs_umount_begin, 467 .remount_fs = cifs_remount, 468 }; 469 470 static int ··· 509 static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) 510 { 511 /* origin == SEEK_END => we must revalidate the cached file length */ 512 - if (origin == 2) { 513 int retval = cifs_revalidate(file->f_dentry); 514 if (retval < 0) 515 return (loff_t)retval; ··· 917 #ifdef CONFIG_PROC_FS 918 cifs_proc_init(); 919 #endif 920 - INIT_LIST_HEAD(&GlobalServerList); /* BB not implemented yet */ 921 INIT_LIST_HEAD(&GlobalSMBSessionList); 922 INIT_LIST_HEAD(&GlobalTreeConnectionList); 923 INIT_LIST_HEAD(&GlobalOplock_Q); ··· 945 GlobalCurrentXid = 0; 946 GlobalTotalActiveXid = 0; 947 GlobalMaxActiveXid = 0; 948 rwlock_init(&GlobalSMBSeslock); 949 spin_lock_init(&GlobalMid_Lock); 950
··· 63 struct task_struct * oplockThread = NULL; 64 extern struct task_struct * dnotifyThread; /* remove sparse warning */ 65 struct task_struct * dnotifyThread = NULL; 66 + static struct super_operations cifs_super_ops; 67 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 68 module_param(CIFSMaxBufSize, int, 0); 69 MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); ··· 198 /* Only need to call the old QFSInfo if failed 199 on newer one */ 200 if(rc) 201 + if(pTcon->ses->capabilities & CAP_NT_SMBS) 202 + rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ 203 204 + /* Some old Windows servers also do not support level 103, retry with 205 + older level one if old server failed the previous call or we 206 + bypassed it because we detected that this was an older LANMAN sess */ 207 if(rc) 208 rc = SMBOldQFSInfo(xid, pTcon, buf); 209 /* ··· 435 return; 436 } 437 438 + #ifdef CONFIG_CIFS_STATS2 439 + static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt) 440 + { 441 + /* BB FIXME */ 442 + return 0; 443 + } 444 + #endif 445 + 446 static int cifs_remount(struct super_block *sb, int *flags, char *data) 447 { 448 *flags |= MS_NODIRATIME; 449 return 0; 450 } 451 452 + static struct super_operations cifs_super_ops = { 453 .read_inode = cifs_read_inode, 454 .put_super = cifs_put_super, 455 .statfs = cifs_statfs, ··· 454 .show_options = cifs_show_options, 455 .umount_begin = cifs_umount_begin, 456 .remount_fs = cifs_remount, 457 + #ifdef CONFIG_CIFS_STATS2 458 + .show_stats = cifs_show_stats, 459 + #endif 460 }; 461 462 static int ··· 495 static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) 496 { 497 /* origin == SEEK_END => we must revalidate the cached file length */ 498 + if (origin == SEEK_END) { 499 int retval = cifs_revalidate(file->f_dentry); 500 if (retval < 0) 501 return (loff_t)retval; ··· 903 #ifdef CONFIG_PROC_FS 904 cifs_proc_init(); 905 #endif 906 + /* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */ 907 INIT_LIST_HEAD(&GlobalSMBSessionList); 908 INIT_LIST_HEAD(&GlobalTreeConnectionList); 909 INIT_LIST_HEAD(&GlobalOplock_Q); ··· 931 GlobalCurrentXid = 0; 932 GlobalTotalActiveXid = 0; 933 GlobalMaxActiveXid = 0; 934 + memset(Local_System_Name, 0, 15); 935 rwlock_init(&GlobalSMBSeslock); 936 spin_lock_init(&GlobalMid_Lock); 937
+1 -1
fs/cifs/cifsfs.h
··· 36 extern const struct address_space_operations cifs_addr_ops_smallbuf; 37 38 /* Functions related to super block operations */ 39 - extern struct super_operations cifs_super_ops; 40 extern void cifs_read_inode(struct inode *); 41 extern void cifs_delete_inode(struct inode *); 42 /* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
··· 36 extern const struct address_space_operations cifs_addr_ops_smallbuf; 37 38 /* Functions related to super block operations */ 39 + /* extern struct super_operations cifs_super_ops;*/ 40 extern void cifs_read_inode(struct inode *); 41 extern void cifs_delete_inode(struct inode *); 42 /* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
+10 -5
fs/cifs/cifsglob.h
··· 153 char sessid[4]; /* unique token id for this session */ 154 /* (returned on Negotiate */ 155 int capabilities; /* allow selective disabling of caps by smb sess */ 156 - __u16 timeZone; 157 __u16 CurrentMid; /* multiplex id - rotating counter */ 158 char cryptKey[CIFS_CRYPTO_KEY_SIZE]; 159 /* 16th byte of RFC1001 workstation name is always null */ ··· 203 char * domainName; 204 char * password; 205 }; 206 - /* session flags */ 207 #define CIFS_SES_NT4 1 208 - 209 /* 210 * there is one of these for each connection to a resource on a particular 211 * session ··· 517 * This list helps improve performance and eliminate the messages indicating 518 * that we had a communications error talking to the server in this list. 519 */ 520 - GLOBAL_EXTERN struct servers_not_supported *NotSuppList; /*@z4a */ 521 522 /* 523 * The following is a hash table of all the users we know about. ··· 574 GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 575 with more secure ntlmssp2 challenge/resp */ 576 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ 577 - GLOBAL_EXTERN unsigned int secFlags; 578 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ 579 GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ 580 GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
··· 153 char sessid[4]; /* unique token id for this session */ 154 /* (returned on Negotiate */ 155 int capabilities; /* allow selective disabling of caps by smb sess */ 156 + int timeAdj; /* Adjust for difference in server time zone in sec */ 157 __u16 CurrentMid; /* multiplex id - rotating counter */ 158 char cryptKey[CIFS_CRYPTO_KEY_SIZE]; 159 /* 16th byte of RFC1001 workstation name is always null */ ··· 203 char * domainName; 204 char * password; 205 }; 206 + /* no more than one of the following three session flags may be set */ 207 #define CIFS_SES_NT4 1 208 + #define CIFS_SES_OS2 2 209 + #define CIFS_SES_W9X 4 210 + /* following flag is set for old servers such as OS2 (and Win95?) 211 + which do not negotiate NTLM or POSIX dialects, but instead 212 + negotiate one of the older LANMAN dialects */ 213 + #define CIFS_SES_LANMAN 8 214 /* 215 * there is one of these for each connection to a resource on a particular 216 * session ··· 512 * This list helps improve performance and eliminate the messages indicating 513 * that we had a communications error talking to the server in this list. 514 */ 515 + /* Feature not supported */ 516 + /* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */ 517 518 /* 519 * The following is a hash table of all the users we know about. ··· 568 GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 569 with more secure ntlmssp2 challenge/resp */ 570 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ 571 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ 572 GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ 573 GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
+9 -3
fs/cifs/cifspdu.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 ··· 409 410 /* Dialect index is 13 for LANMAN */ 411 412 typedef struct lanman_neg_rsp { 413 struct smb_hdr hdr; /* wct = 13 */ 414 __le16 DialectIndex; ··· 420 __le16 MaxNumberVcs; 421 __le16 RawMode; 422 __le32 SessionKey; 423 - __le32 ServerTime; 424 __le16 ServerTimeZone; 425 __le16 EncryptionKeyLength; 426 __le16 Reserved; ··· 680 typedef struct smb_com_close_req { 681 struct smb_hdr hdr; /* wct = 3 */ 682 __u16 FileID; 683 - __u32 LastWriteTime; /* should be zero */ 684 __u16 ByteCount; /* 0 */ 685 } __attribute__((packed)) CLOSE_REQ; 686
··· 26 27 #ifdef CONFIG_CIFS_WEAK_PW_HASH 28 #define LANMAN_PROT 0 29 + #define LANMAN2_PROT 1 30 + #define CIFS_PROT 2 31 #else 32 #define CIFS_PROT 0 33 #endif ··· 408 409 /* Dialect index is 13 for LANMAN */ 410 411 + #define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */ 412 + 413 typedef struct lanman_neg_rsp { 414 struct smb_hdr hdr; /* wct = 13 */ 415 __le16 DialectIndex; ··· 417 __le16 MaxNumberVcs; 418 __le16 RawMode; 419 __le32 SessionKey; 420 + struct { 421 + __le16 Time; 422 + __le16 Date; 423 + } __attribute__((packed)) SrvTime; 424 __le16 ServerTimeZone; 425 __le16 EncryptionKeyLength; 426 __le16 Reserved; ··· 674 typedef struct smb_com_close_req { 675 struct smb_hdr hdr; /* wct = 3 */ 676 __u16 FileID; 677 + __u32 LastWriteTime; /* should be zero or -1 */ 678 __u16 ByteCount; /* 0 */ 679 } __attribute__((packed)) CLOSE_REQ; 680
+7 -5
fs/cifs/cifsproto.h
··· 50 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 51 struct kvec *, int /* nvec to send */, 52 int * /* type of buf returned */ , const int long_op); 53 - extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *, 54 struct smb_hdr * /* input */ , 55 struct smb_hdr * /* out */ , 56 int * /* bytes returned */); 57 - extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); 58 - extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); 59 extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); 60 extern int is_size_safe_to_change(struct cifsInodeInfo *); 61 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); ··· 80 extern void DeleteOplockQEntry(struct oplock_q_entry *); 81 extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); 82 extern u64 cifs_UnixTimeToNT(struct timespec); 83 extern int cifs_get_inode_info(struct inode **pinode, 84 const unsigned char *search_path, 85 FILE_ALL_INFO * pfile_info, ··· 119 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 120 const unsigned char *searchName, 121 FILE_ALL_INFO * findData, 122 const struct nls_table *nls_codepage, int remap); 123 extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 124 const unsigned char *searchName, ··· 282 extern void sesInfoFree(struct cifsSesInfo *); 283 extern struct cifsTconInfo *tconInfoAlloc(void); 284 extern void tconInfoFree(struct cifsTconInfo *); 285 - 286 - extern int cifs_reconnect(struct TCP_Server_Info *server); 287 288 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); 289 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
··· 50 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 51 struct kvec *, int /* nvec to send */, 52 int * /* type of buf returned */ , const int long_op); 53 + extern int SendReceiveBlockingLock(const unsigned int /* xid */ , 54 + struct cifsTconInfo *, 55 struct smb_hdr * /* input */ , 56 struct smb_hdr * /* out */ , 57 int * /* bytes returned */); 58 + extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); 59 extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); 60 extern int is_size_safe_to_change(struct cifsInodeInfo *); 61 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); ··· 80 extern void DeleteOplockQEntry(struct oplock_q_entry *); 81 extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); 82 extern u64 cifs_UnixTimeToNT(struct timespec); 83 + extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); 84 + extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); 85 + 86 extern int cifs_get_inode_info(struct inode **pinode, 87 const unsigned char *search_path, 88 FILE_ALL_INFO * pfile_info, ··· 116 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 117 const unsigned char *searchName, 118 FILE_ALL_INFO * findData, 119 + int legacy /* whether to use old info level */, 120 const struct nls_table *nls_codepage, int remap); 121 extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 122 const unsigned char *searchName, ··· 278 extern void sesInfoFree(struct cifsSesInfo *); 279 extern struct cifsTconInfo *tconInfoAlloc(void); 280 extern void tconInfoFree(struct cifsTconInfo *); 281 282 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); 283 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
+83 -13
fs/cifs/cifssmb.c
··· 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"}, ··· 59 } protocols[] = { 60 #ifdef CONFIG_CIFS_WEAK_PW_HASH 61 {LANMAN_PROT, "\2LM1.2X002"}, 62 #endif /* weak password hashing for legacy clients */ 63 {CIFS_PROT, "\2NT LM 0.12"}, 64 {BAD_PROT, "\2"} ··· 69 /* define the number of elements in the cifs dialect array */ 70 #ifdef CONFIG_CIFS_POSIX 71 #ifdef CONFIG_CIFS_WEAK_PW_HASH 72 - #define CIFS_NUM_PROT 3 73 #else 74 #define CIFS_NUM_PROT 2 75 #endif /* CIFS_WEAK_PW_HASH */ 76 #else /* not posix */ 77 #ifdef CONFIG_CIFS_WEAK_PW_HASH 78 - #define CIFS_NUM_PROT 2 79 #else 80 #define CIFS_NUM_PROT 1 81 #endif /* CONFIG_CIFS_WEAK_PW_HASH */ ··· 448 goto neg_err_exit; 449 #ifdef CONFIG_CIFS_WEAK_PW_HASH 450 } else if((pSMBr->hdr.WordCount == 13) 451 - && (pSMBr->DialectIndex == LANMAN_PROT)) { 452 struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; 453 454 if((secFlags & CIFSSEC_MAY_LANMAN) || ··· 476 server->maxRw = 0;/* we do not need to use raw anyway */ 477 server->capabilities = CAP_MPX_MODE; 478 } 479 - server->timeZone = le16_to_cpu(rsp->ServerTimeZone); 480 481 /* BB get server time for time conversions and add 482 code to use it and timezone since this is not UTC */ 483 484 - if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 485 memcpy(server->cryptKey, rsp->EncryptionKey, 486 CIFS_CRYPTO_KEY_SIZE); 487 } else if (server->secMode & SECMODE_PW_ENCRYPT) { ··· 567 cFYI(0, ("Max buf = %d", ses->server->maxBuf)); 568 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); 569 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 570 - server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); 571 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 572 memcpy(server->cryptKey, pSMBr->u.EncryptionKey, 573 CIFS_CRYPTO_KEY_SIZE); ··· 1654 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ 1655 1656 pSMB->FileID = (__u16) smb_file_id; 1657 - pSMB->LastWriteTime = 0; 1658 pSMB->ByteCount = 0; 1659 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1660 (struct smb_hdr *) pSMBr, &bytes_returned, 0); ··· 2810 2811 2812 /* security id for everyone */ 2813 - const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; 2814 /* group users */ 2815 - const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 2816 2817 /* Convert CIFS ACL to POSIX form */ 2818 static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) ··· 2895 return rc; 2896 } 2897 2898 - 2899 /* Legacy Query Path Information call for lookup to old servers such 2900 as Win9x/WinME */ 2901 int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, ··· 2936 if (rc) { 2937 cFYI(1, ("Send error in QueryInfo = %d", rc)); 2938 } else if (pFinfo) { /* decode response */ 2939 memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); 2940 pFinfo->AllocationSize = 2941 cpu_to_le64(le32_to_cpu(pSMBr->size)); 2942 pFinfo->EndOfFile = pFinfo->AllocationSize; ··· 2969 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 2970 const unsigned char *searchName, 2971 FILE_ALL_INFO * pFindData, 2972 const struct nls_table *nls_codepage, int remap) 2973 { 2974 /* level 263 SMB_QUERY_FILE_ALL_INFO */ ··· 3018 byte_count = params + 1 /* pad */ ; 3019 pSMB->TotalParameterCount = cpu_to_le16(params); 3020 pSMB->ParameterCount = pSMB->TotalParameterCount; 3021 - pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3022 pSMB->Reserved4 = 0; 3023 pSMB->hdr.smb_buf_length += byte_count; 3024 pSMB->ByteCount = cpu_to_le16(byte_count); ··· 3033 } else { /* decode response */ 3034 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3035 3036 - if (rc || (pSMBr->ByteCount < 40)) 3037 rc = -EIO; /* bad smb */ 3038 else if (pFindData){ 3039 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3040 memcpy((char *) pFindData, 3041 (char *) &pSMBr->hdr.Protocol + 3042 - data_offset, sizeof (FILE_ALL_INFO)); 3043 } else 3044 rc = -ENOMEM; 3045 } ··· 3674 name_len++; /* trailing null */ 3675 strncpy(pSMB->RequestFileName, searchName, name_len); 3676 } 3677 3678 params = 2 /* level */ + name_len /*includes null */ ; 3679 pSMB->TotalDataCount = 0;
··· 46 } protocols[] = { 47 #ifdef CONFIG_CIFS_WEAK_PW_HASH 48 {LANMAN_PROT, "\2LM1.2X002"}, 49 + {LANMAN2_PROT, "\2LANMAN2.1"}, 50 #endif /* weak password hashing for legacy clients */ 51 {CIFS_PROT, "\2NT LM 0.12"}, 52 {POSIX_PROT, "\2POSIX 2"}, ··· 58 } protocols[] = { 59 #ifdef CONFIG_CIFS_WEAK_PW_HASH 60 {LANMAN_PROT, "\2LM1.2X002"}, 61 + {LANMAN2_PROT, "\2LANMAN2.1"}, 62 #endif /* weak password hashing for legacy clients */ 63 {CIFS_PROT, "\2NT LM 0.12"}, 64 {BAD_PROT, "\2"} ··· 67 /* define the number of elements in the cifs dialect array */ 68 #ifdef CONFIG_CIFS_POSIX 69 #ifdef CONFIG_CIFS_WEAK_PW_HASH 70 + #define CIFS_NUM_PROT 4 71 #else 72 #define CIFS_NUM_PROT 2 73 #endif /* CIFS_WEAK_PW_HASH */ 74 #else /* not posix */ 75 #ifdef CONFIG_CIFS_WEAK_PW_HASH 76 + #define CIFS_NUM_PROT 3 77 #else 78 #define CIFS_NUM_PROT 1 79 #endif /* CONFIG_CIFS_WEAK_PW_HASH */ ··· 446 goto neg_err_exit; 447 #ifdef CONFIG_CIFS_WEAK_PW_HASH 448 } else if((pSMBr->hdr.WordCount == 13) 449 + && ((pSMBr->DialectIndex == LANMAN_PROT) 450 + || (pSMBr->DialectIndex == LANMAN2_PROT))) { 451 + __s16 tmp; 452 struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; 453 454 if((secFlags & CIFSSEC_MAY_LANMAN) || ··· 472 server->maxRw = 0;/* we do not need to use raw anyway */ 473 server->capabilities = CAP_MPX_MODE; 474 } 475 + tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); 476 + if (tmp == -1) { 477 + /* OS/2 often does not set timezone therefore 478 + * we must use server time to calc time zone. 479 + * Could deviate slightly from the right zone. 480 + * Smallest defined timezone difference is 15 minutes 481 + * (i.e. Nepal). Rounding up/down is done to match 482 + * this requirement. 483 + */ 484 + int val, seconds, remain, result; 485 + struct timespec ts, utc; 486 + utc = CURRENT_TIME; 487 + ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), 488 + le16_to_cpu(rsp->SrvTime.Time)); 489 + cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d", 490 + (int)ts.tv_sec, (int)utc.tv_sec, 491 + (int)(utc.tv_sec - ts.tv_sec))); 492 + val = (int)(utc.tv_sec - ts.tv_sec); 493 + seconds = val < 0 ? -val : val; 494 + result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; 495 + remain = seconds % MIN_TZ_ADJ; 496 + if(remain >= (MIN_TZ_ADJ / 2)) 497 + result += MIN_TZ_ADJ; 498 + if(val < 0) 499 + result = - result; 500 + server->timeAdj = result; 501 + } else { 502 + server->timeAdj = (int)tmp; 503 + server->timeAdj *= 60; /* also in seconds */ 504 + } 505 + cFYI(1,("server->timeAdj: %d seconds", server->timeAdj)); 506 + 507 508 /* BB get server time for time conversions and add 509 code to use it and timezone since this is not UTC */ 510 511 + if (rsp->EncryptionKeyLength == 512 + cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 513 memcpy(server->cryptKey, rsp->EncryptionKey, 514 CIFS_CRYPTO_KEY_SIZE); 515 } else if (server->secMode & SECMODE_PW_ENCRYPT) { ··· 531 cFYI(0, ("Max buf = %d", ses->server->maxBuf)); 532 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); 533 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 534 + server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); 535 + server->timeAdj *= 60; 536 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 537 memcpy(server->cryptKey, pSMBr->u.EncryptionKey, 538 CIFS_CRYPTO_KEY_SIZE); ··· 1617 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ 1618 1619 pSMB->FileID = (__u16) smb_file_id; 1620 + pSMB->LastWriteTime = 0xFFFFFFFF; 1621 pSMB->ByteCount = 0; 1622 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1623 (struct smb_hdr *) pSMBr, &bytes_returned, 0); ··· 2773 2774 2775 /* security id for everyone */ 2776 + const static struct cifs_sid sid_everyone = 2777 + {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; 2778 /* group users */ 2779 + const static struct cifs_sid sid_user = 2780 + {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 2781 2782 /* Convert CIFS ACL to POSIX form */ 2783 static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) ··· 2856 return rc; 2857 } 2858 2859 /* Legacy Query Path Information call for lookup to old servers such 2860 as Win9x/WinME */ 2861 int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, ··· 2898 if (rc) { 2899 cFYI(1, ("Send error in QueryInfo = %d", rc)); 2900 } else if (pFinfo) { /* decode response */ 2901 + struct timespec ts; 2902 + __u32 time = le32_to_cpu(pSMBr->last_write_time); 2903 + /* BB FIXME - add time zone adjustment BB */ 2904 memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); 2905 + ts.tv_nsec = 0; 2906 + ts.tv_sec = time; 2907 + /* decode time fields */ 2908 + pFinfo->ChangeTime = cifs_UnixTimeToNT(ts); 2909 + pFinfo->LastWriteTime = pFinfo->ChangeTime; 2910 + pFinfo->LastAccessTime = 0; 2911 pFinfo->AllocationSize = 2912 cpu_to_le64(le32_to_cpu(pSMBr->size)); 2913 pFinfo->EndOfFile = pFinfo->AllocationSize; ··· 2922 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 2923 const unsigned char *searchName, 2924 FILE_ALL_INFO * pFindData, 2925 + int legacy /* old style infolevel */, 2926 const struct nls_table *nls_codepage, int remap) 2927 { 2928 /* level 263 SMB_QUERY_FILE_ALL_INFO */ ··· 2970 byte_count = params + 1 /* pad */ ; 2971 pSMB->TotalParameterCount = cpu_to_le16(params); 2972 pSMB->ParameterCount = pSMB->TotalParameterCount; 2973 + if(legacy) 2974 + pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 2975 + else 2976 + pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 2977 pSMB->Reserved4 = 0; 2978 pSMB->hdr.smb_buf_length += byte_count; 2979 pSMB->ByteCount = cpu_to_le16(byte_count); ··· 2982 } else { /* decode response */ 2983 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2984 2985 + if (rc) /* BB add auto retry on EOPNOTSUPP? */ 2986 + rc = -EIO; 2987 + else if (!legacy && (pSMBr->ByteCount < 40)) 2988 rc = -EIO; /* bad smb */ 2989 + else if(legacy && (pSMBr->ByteCount < 24)) 2990 + rc = -EIO; /* 24 or 26 expected but we do not read last field */ 2991 else if (pFindData){ 2992 + int size; 2993 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2994 + if(legacy) /* we do not read the last field, EAsize, fortunately 2995 + since it varies by subdialect and on Set vs. Get, is 2996 + two bytes or 4 bytes depending but we don't care here */ 2997 + size = sizeof(FILE_INFO_STANDARD); 2998 + else 2999 + size = sizeof(FILE_ALL_INFO); 3000 memcpy((char *) pFindData, 3001 (char *) &pSMBr->hdr.Protocol + 3002 + data_offset, size); 3003 } else 3004 rc = -ENOMEM; 3005 } ··· 3612 name_len++; /* trailing null */ 3613 strncpy(pSMB->RequestFileName, searchName, name_len); 3614 } 3615 + 3616 + if(ses->server) { 3617 + if(ses->server->secMode & 3618 + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3619 + pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3620 + } 3621 + 3622 + pSMB->hdr.Uid = ses->Suid; 3623 3624 params = 2 /* level */ + name_len /*includes null */ ; 3625 pSMB->TotalDataCount = 0;
+22 -13
fs/cifs/connect.c
··· 109 * wake up waiters on reconnection? - (not needed currently) 110 */ 111 112 - int 113 cifs_reconnect(struct TCP_Server_Info *server) 114 { 115 int rc = 0; ··· 771 separator[0] = ','; 772 separator[1] = 0; 773 774 - memset(vol->source_rfc1001_name,0x20,15); 775 - for(i=0;i < strnlen(utsname()->nodename,15);i++) { 776 - /* does not have to be a perfect mapping since the field is 777 - informational, only used for servers that do not support 778 - port 445 and it can be overridden at mount time */ 779 - vol->source_rfc1001_name[i] = 780 - toupper(utsname()->nodename[i]); 781 } 782 vol->source_rfc1001_name[15] = 0; 783 /* null target name indicates to use *SMBSERVR default called name ··· 3220 } 3221 /* else do not bother copying these informational fields */ 3222 } 3223 - if(smb_buffer_response->WordCount == 3) 3224 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3225 else 3226 tcon->Flags = 0; ··· 3319 first_time = 1; 3320 } 3321 if (!rc) { 3322 pSesInfo->capabilities = pSesInfo->server->capabilities; 3323 if(linuxExtEnabled == 0) 3324 pSesInfo->capabilities &= (~CAP_UNIX); 3325 /* pSesInfo->sequence_number = 0;*/ 3326 - cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d", 3327 pSesInfo->server->secMode, 3328 pSesInfo->server->capabilities, 3329 - pSesInfo->server->timeZone)); 3330 if(experimEnabled < 2) 3331 rc = CIFS_SessSetup(xid, pSesInfo, 3332 first_time, nls_info); 3333 else if (extended_security 3334 - && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3335 && (pSesInfo->server->secType == NTLMSSP)) { 3336 rc = -EOPNOTSUPP; 3337 } else if (extended_security ··· 3347 if (!rc) { 3348 if(ntlmv2_flag) { 3349 char * v2_response; 3350 - cFYI(1,("Can use more secure NTLM version 2 password hash")); 3351 if(CalcNTLMv2_partial_mac_key(pSesInfo, 3352 nls_info)) { 3353 rc = -ENOMEM;
··· 109 * wake up waiters on reconnection? - (not needed currently) 110 */ 111 112 + static int 113 cifs_reconnect(struct TCP_Server_Info *server) 114 { 115 int rc = 0; ··· 771 separator[0] = ','; 772 separator[1] = 0; 773 774 + if (Local_System_Name[0] != 0) 775 + memcpy(vol->source_rfc1001_name, Local_System_Name,15); 776 + else { 777 + char *nodename = utsname()->nodename; 778 + int n = strnlen(nodename,15); 779 + memset(vol->source_rfc1001_name,0x20,15); 780 + for(i=0 ; i < n ; i++) { 781 + /* does not have to be perfect mapping since field is 782 + informational, only used for servers that do not support 783 + port 445 and it can be overridden at mount time */ 784 + vol->source_rfc1001_name[i] = toupper(nodename[i]); 785 + } 786 } 787 vol->source_rfc1001_name[15] = 0; 788 /* null target name indicates to use *SMBSERVR default called name ··· 3215 } 3216 /* else do not bother copying these informational fields */ 3217 } 3218 + if((smb_buffer_response->WordCount == 3) || 3219 + (smb_buffer_response->WordCount == 7)) 3220 + /* field is in same location */ 3221 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3222 else 3223 tcon->Flags = 0; ··· 3312 first_time = 1; 3313 } 3314 if (!rc) { 3315 + pSesInfo->flags = 0; 3316 pSesInfo->capabilities = pSesInfo->server->capabilities; 3317 if(linuxExtEnabled == 0) 3318 pSesInfo->capabilities &= (~CAP_UNIX); 3319 /* pSesInfo->sequence_number = 0;*/ 3320 + cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 3321 pSesInfo->server->secMode, 3322 pSesInfo->server->capabilities, 3323 + pSesInfo->server->timeAdj)); 3324 if(experimEnabled < 2) 3325 rc = CIFS_SessSetup(xid, pSesInfo, 3326 first_time, nls_info); 3327 else if (extended_security 3328 + && (pSesInfo->capabilities 3329 + & CAP_EXTENDED_SECURITY) 3330 && (pSesInfo->server->secType == NTLMSSP)) { 3331 rc = -EOPNOTSUPP; 3332 } else if (extended_security ··· 3338 if (!rc) { 3339 if(ntlmv2_flag) { 3340 char * v2_response; 3341 + cFYI(1,("more secure NTLM ver2 hash")); 3342 if(CalcNTLMv2_partial_mac_key(pSesInfo, 3343 nls_info)) { 3344 rc = -ENOMEM;
+9 -3
fs/cifs/inode.c
··· 337 pfindData = (FILE_ALL_INFO *)buf; 338 /* could do find first instead but this returns more info */ 339 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 340 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 341 CIFS_MOUNT_MAP_SPECIAL_CHR); 342 /* BB optimize code so we do not make the above call ··· 385 /* get new inode */ 386 if (*pinode == NULL) { 387 *pinode = new_inode(sb); 388 - if (*pinode == NULL) 389 return -ENOMEM; 390 /* Is an i_ino of zero legal? Can we use that to check 391 if the server supports returning inode numbers? Are 392 there other sanity checks we can use to ensure that ··· 434 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 435 436 /* Linux can not store file creation time so ignore it */ 437 - inode->i_atime = 438 - cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); 439 inode->i_mtime = 440 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 441 inode->i_ctime =
··· 337 pfindData = (FILE_ALL_INFO *)buf; 338 /* could do find first instead but this returns more info */ 339 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 340 + 0 /* not legacy */, 341 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 342 CIFS_MOUNT_MAP_SPECIAL_CHR); 343 /* BB optimize code so we do not make the above call ··· 384 /* get new inode */ 385 if (*pinode == NULL) { 386 *pinode = new_inode(sb); 387 + if (*pinode == NULL) { 388 + kfree(buf); 389 return -ENOMEM; 390 + } 391 /* Is an i_ino of zero legal? Can we use that to check 392 if the server supports returning inode numbers? Are 393 there other sanity checks we can use to ensure that ··· 431 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 432 433 /* Linux can not store file creation time so ignore it */ 434 + if(pfindData->LastAccessTime) 435 + inode->i_atime = cifs_NTtimeToUnix 436 + (le64_to_cpu(pfindData->LastAccessTime)); 437 + else /* do not need to use current_fs_time - time not stored */ 438 + inode->i_atime = CURRENT_TIME; 439 inode->i_mtime = 440 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 441 inode->i_ctime =
+5 -1
fs/cifs/link.c
··· 254 tmpbuffer, 255 len - 1, 256 cifs_sb->local_nls); 257 - else { 258 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, 259 OPEN_REPARSE_POINT,&fid, &oplock, NULL, 260 cifs_sb->local_nls,
··· 254 tmpbuffer, 255 len - 1, 256 cifs_sb->local_nls); 257 + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 258 + cERROR(1,("SFU style symlinks not implemented yet")); 259 + /* add open and read as in fs/cifs/inode.c */ 260 + 261 + } else { 262 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, 263 OPEN_REPARSE_POINT,&fid, &oplock, NULL, 264 cifs_sb->local_nls,
+6 -2
fs/cifs/md5.c
··· 252 buf[3] += d; 253 } 254 255 /*********************************************************************** 256 the rfc 2104 version of hmac_md5 initialisation. 257 ***********************************************************************/ 258 - void 259 hmac_md5_init_rfc2104(unsigned char *key, int key_len, 260 struct HMACMD5Context *ctx) 261 { ··· 290 MD5Init(&ctx->ctx); 291 MD5Update(&ctx->ctx, ctx->k_ipad, 64); 292 } 293 294 /*********************************************************************** 295 the microsoft version of hmac_md5 initialisation. ··· 352 single function to calculate an HMAC MD5 digest from data. 353 use the microsoft hmacmd5 init method because the key is 16 bytes. 354 ************************************************************/ 355 - void 356 hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 357 unsigned char *digest) 358 { ··· 364 } 365 hmac_md5_final(digest, &ctx); 366 }
··· 252 buf[3] += d; 253 } 254 255 + #if 0 /* currently unused */ 256 /*********************************************************************** 257 the rfc 2104 version of hmac_md5 initialisation. 258 ***********************************************************************/ 259 + static void 260 hmac_md5_init_rfc2104(unsigned char *key, int key_len, 261 struct HMACMD5Context *ctx) 262 { ··· 289 MD5Init(&ctx->ctx); 290 MD5Update(&ctx->ctx, ctx->k_ipad, 64); 291 } 292 + #endif 293 294 /*********************************************************************** 295 the microsoft version of hmac_md5 initialisation. ··· 350 single function to calculate an HMAC MD5 digest from data. 351 use the microsoft hmacmd5 init method because the key is 16 bytes. 352 ************************************************************/ 353 + #if 0 /* currently unused */ 354 + static void 355 hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 356 unsigned char *digest) 357 { ··· 361 } 362 hmac_md5_final(digest, &ctx); 363 } 364 + #endif
+4 -4
fs/cifs/md5.h
··· 27 28 /* The following definitions come from lib/hmacmd5.c */ 29 30 - void hmac_md5_init_rfc2104(unsigned char *key, int key_len, 31 - struct HMACMD5Context *ctx); 32 void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, 33 struct HMACMD5Context *ctx); 34 void hmac_md5_update(const unsigned char *text, int text_len, 35 struct HMACMD5Context *ctx); 36 void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); 37 - void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 38 - unsigned char *digest);
··· 27 28 /* The following definitions come from lib/hmacmd5.c */ 29 30 + /* void hmac_md5_init_rfc2104(unsigned char *key, int key_len, 31 + struct HMACMD5Context *ctx);*/ 32 void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, 33 struct HMACMD5Context *ctx); 34 void hmac_md5_update(const unsigned char *text, int text_len, 35 struct HMACMD5Context *ctx); 36 void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); 37 + /* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 38 + unsigned char *digest);*/
+30 -14
fs/cifs/misc.c
··· 389 return; 390 } 391 392 - int 393 checkSMBhdr(struct smb_hdr *smb, __u16 mid) 394 { 395 /* Make sure that this really is an SMB, that it is a response, ··· 418 } 419 420 int 421 - checkSMB(struct smb_hdr *smb, __u16 mid, int length) 422 { 423 __u32 len = smb->smb_buf_length; 424 __u32 clc_len; /* calculated length */ 425 cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); 426 - if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || 427 - (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { 428 - if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { 429 - if (((unsigned int)length >= 430 - sizeof (struct smb_hdr) - 1) 431 && (smb->Status.CifsError != 0)) { 432 - smb->WordCount = 0; 433 - /* some error cases do not return wct and bcc */ 434 return 0; 435 - } else { 436 - cERROR(1, ("Length less than smb header size")); 437 } 438 } 439 - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) 440 - cERROR(1, ("smb length greater than MaxBufSize, mid=%d", 441 smb->Mid)); 442 return 1; 443 } ··· 462 return 1; 463 clc_len = smbCalcSize_LE(smb); 464 465 - if(4 + len != (unsigned int)length) { 466 cERROR(1, ("Length read does not match RFC1001 length %d",len)); 467 return 1; 468 }
··· 389 return; 390 } 391 392 + static int 393 checkSMBhdr(struct smb_hdr *smb, __u16 mid) 394 { 395 /* Make sure that this really is an SMB, that it is a response, ··· 418 } 419 420 int 421 + checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) 422 { 423 __u32 len = smb->smb_buf_length; 424 __u32 clc_len; /* calculated length */ 425 cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); 426 + 427 + if (length < 2 + sizeof (struct smb_hdr)) { 428 + if ((length >= sizeof (struct smb_hdr) - 1) 429 && (smb->Status.CifsError != 0)) { 430 + smb->WordCount = 0; 431 + /* some error cases do not return wct and bcc */ 432 + return 0; 433 + } else if ((length == sizeof(struct smb_hdr) + 1) && 434 + (smb->WordCount == 0)) { 435 + char * tmp = (char *)smb; 436 + /* Need to work around a bug in two servers here */ 437 + /* First, check if the part of bcc they sent was zero */ 438 + if (tmp[sizeof(struct smb_hdr)] == 0) { 439 + /* some servers return only half of bcc 440 + * on simple responses (wct, bcc both zero) 441 + * in particular have seen this on 442 + * ulogoffX and FindClose. This leaves 443 + * one byte of bcc potentially unitialized 444 + */ 445 + /* zero rest of bcc */ 446 + tmp[sizeof(struct smb_hdr)+1] = 0; 447 return 0; 448 } 449 + cERROR(1,("rcvd invalid byte count (bcc)")); 450 + } else { 451 + cERROR(1, ("Length less than smb header size")); 452 } 453 + return 1; 454 + } 455 + if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 456 + cERROR(1, ("smb length greater than MaxBufSize, mid=%d", 457 smb->Mid)); 458 return 1; 459 } ··· 446 return 1; 447 clc_len = smbCalcSize_LE(smb); 448 449 + if(4 + len != length) { 450 cERROR(1, ("Length read does not match RFC1001 length %d",len)); 451 return 1; 452 }
+58
fs/cifs/netmisc.c
··· 909 /* Convert to 100ns intervals and then add the NTFS time offset. */ 910 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; 911 }
··· 909 /* Convert to 100ns intervals and then add the NTFS time offset. */ 910 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; 911 } 912 + 913 + static int total_days_of_prev_months[] = 914 + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; 915 + 916 + 917 + __le64 cnvrtDosCifsTm(__u16 date, __u16 time) 918 + { 919 + return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time))); 920 + } 921 + 922 + struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) 923 + { 924 + struct timespec ts; 925 + int sec, min, days, month, year; 926 + SMB_TIME * st = (SMB_TIME *)&time; 927 + SMB_DATE * sd = (SMB_DATE *)&date; 928 + 929 + cFYI(1,("date %d time %d",date, time)); 930 + 931 + sec = 2 * st->TwoSeconds; 932 + min = st->Minutes; 933 + if((sec > 59) || (min > 59)) 934 + cERROR(1,("illegal time min %d sec %d", min, sec)); 935 + sec += (min * 60); 936 + sec += 60 * 60 * st->Hours; 937 + if(st->Hours > 24) 938 + cERROR(1,("illegal hours %d",st->Hours)); 939 + days = sd->Day; 940 + month = sd->Month; 941 + if((days > 31) || (month > 12)) 942 + cERROR(1,("illegal date, month %d day: %d", month, days)); 943 + month -= 1; 944 + days += total_days_of_prev_months[month]; 945 + days += 3652; /* account for difference in days between 1980 and 1970 */ 946 + year = sd->Year; 947 + days += year * 365; 948 + days += (year/4); /* leap year */ 949 + /* generalized leap year calculation is more complex, ie no leap year 950 + for years/100 except for years/400, but since the maximum number for DOS 951 + year is 2**7, the last year is 1980+127, which means we need only 952 + consider 2 special case years, ie the years 2000 and 2100, and only 953 + adjust for the lack of leap year for the year 2100, as 2000 was a 954 + leap year (divisable by 400) */ 955 + if(year >= 120) /* the year 2100 */ 956 + days = days - 1; /* do not count leap year for the year 2100 */ 957 + 958 + /* adjust for leap year where we are still before leap day */ 959 + if(year != 120) 960 + days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); 961 + sec += 24 * 60 * 60 * days; 962 + 963 + ts.tv_sec = sec; 964 + 965 + /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ 966 + 967 + ts.tv_nsec = 0; 968 + return ts; 969 + }
+23 -4
fs/cifs/readdir.c
··· 106 return rc; 107 } 108 109 static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 110 char * buf, int *pobject_type, int isNewInode) 111 { ··· 146 tmp_inode->i_ctime = 147 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 148 } else { /* legacy, OS2 and DOS style */ 149 FIND_FILE_STANDARD_INFO * pfindData = 150 (FIND_FILE_STANDARD_INFO *)buf; 151 152 attr = le16_to_cpu(pfindData->Attributes); 153 allocation_size = le32_to_cpu(pfindData->AllocationSize); 154 end_of_file = le32_to_cpu(pfindData->DataSize); 155 - tmp_inode->i_atime = CURRENT_TIME; 156 - /* tmp_inode->i_mtime = BB FIXME - add dos time handling 157 - tmp_inode->i_ctime = 0; BB FIXME */ 158 - 159 } 160 161 /* Linux can not store file creation time unfortunately so ignore it */ ··· 956 filename = &pFindData->FileName[0]; 957 /* one byte length, no name conversion */ 958 len = (unsigned int)pFindData->FileNameLength; 959 } else { 960 cFYI(1,("Unknown findfirst level %d",level)); 961 return -EINVAL;
··· 106 return rc; 107 } 108 109 + static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) 110 + { 111 + if((tcon) && (tcon->ses) && (tcon->ses->server)) { 112 + inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; 113 + inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; 114 + inode->i_atime.tv_sec += tcon->ses->server->timeAdj; 115 + } 116 + return; 117 + } 118 + 119 + 120 static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 121 char * buf, int *pobject_type, int isNewInode) 122 { ··· 135 tmp_inode->i_ctime = 136 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 137 } else { /* legacy, OS2 and DOS style */ 138 + /* struct timespec ts;*/ 139 FIND_FILE_STANDARD_INFO * pfindData = 140 (FIND_FILE_STANDARD_INFO *)buf; 141 142 + tmp_inode->i_mtime = cnvrtDosUnixTm( 143 + le16_to_cpu(pfindData->LastWriteDate), 144 + le16_to_cpu(pfindData->LastWriteTime)); 145 + tmp_inode->i_atime = cnvrtDosUnixTm( 146 + le16_to_cpu(pfindData->LastAccessDate), 147 + le16_to_cpu(pfindData->LastAccessTime)); 148 + tmp_inode->i_ctime = cnvrtDosUnixTm( 149 + le16_to_cpu(pfindData->LastWriteDate), 150 + le16_to_cpu(pfindData->LastWriteTime)); 151 + AdjustForTZ(cifs_sb->tcon, tmp_inode); 152 attr = le16_to_cpu(pfindData->Attributes); 153 allocation_size = le32_to_cpu(pfindData->AllocationSize); 154 end_of_file = le32_to_cpu(pfindData->DataSize); 155 } 156 157 /* Linux can not store file creation time unfortunately so ignore it */ ··· 938 filename = &pFindData->FileName[0]; 939 /* one byte length, no name conversion */ 940 len = (unsigned int)pFindData->FileNameLength; 941 + cifsFile->srch_inf.resume_key = pFindData->ResumeKey; 942 } else { 943 cFYI(1,("Unknown findfirst level %d",level)); 944 return -EINVAL;
+12 -11
fs/cifs/sess.c
··· 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; ··· 294 if(len > bleft) 295 return rc; 296 297 - if(ses->serverDomain) 298 - kfree(ses->serverDomain); 299 - 300 - ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); 301 - if(ses->serverOS) 302 - strncpy(ses->serverOS, bcc_ptr, len); 303 - 304 - bcc_ptr += len + 1; 305 - bleft -= len + 1; 306 - 307 cFYI(1,("ascii: bytes left %d",bleft)); 308 309 return rc; ··· 365 str_area = kmalloc(2000, GFP_KERNEL); 366 bcc_ptr = str_area; 367 368 if(type == LANMAN) { 369 #ifdef CONFIG_CIFS_WEAK_PW_HASH 370 char lnm_session_key[CIFS_SESS_KEY_SIZE]; ··· 378 /* and copy into bcc */ 379 380 calc_lanman_hash(ses, lnm_session_key); 381 - 382 /* #ifdef CONFIG_CIFS_DEBUG2 383 cifs_dump_mem("cryptkey: ",ses->server->cryptKey, 384 CIFS_SESS_KEY_SIZE);
··· 268 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 269 if(ses->serverOS) 270 strncpy(ses->serverOS, bcc_ptr, len); 271 + if(strncmp(ses->serverOS, "OS/2",4) == 0) { 272 + cFYI(1,("OS/2 server")); 273 + ses->flags |= CIFS_SES_OS2; 274 + } 275 276 bcc_ptr += len + 1; 277 bleft -= len + 1; ··· 290 if(len > bleft) 291 return rc; 292 293 + /* No domain field in LANMAN case. Domain is 294 + returned by old servers in the SMB negprot response */ 295 + /* BB For newer servers which do not support Unicode, 296 + but thus do return domain here we could add parsing 297 + for it later, but it is not very important */ 298 cFYI(1,("ascii: bytes left %d",bleft)); 299 300 return rc; ··· 366 str_area = kmalloc(2000, GFP_KERNEL); 367 bcc_ptr = str_area; 368 369 + ses->flags &= ~CIFS_SES_LANMAN; 370 + 371 if(type == LANMAN) { 372 #ifdef CONFIG_CIFS_WEAK_PW_HASH 373 char lnm_session_key[CIFS_SESS_KEY_SIZE]; ··· 377 /* and copy into bcc */ 378 379 calc_lanman_hash(ses, lnm_session_key); 380 + ses->flags |= CIFS_SES_LANMAN; 381 /* #ifdef CONFIG_CIFS_DEBUG2 382 cifs_dump_mem("cryptkey: ",ses->server->cryptKey, 383 CIFS_SESS_KEY_SIZE);
+3 -3
fs/cifs/smbdes.c
··· 364 smbhash(p24 + 16, c8, p21 + 14, 1); 365 } 366 367 - void 368 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) 369 { 370 smbhash(out, in, p14, 0); 371 smbhash(out + 8, in + 8, p14 + 7, 0); 372 } 373 374 - void 375 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out) 376 { 377 smbhash(out, in, p14, 1); 378 smbhash(out + 8, in + 8, p14 + 7, 1); 379 } 380 - #if 0 381 /* these routines are currently unneeded, but may be 382 needed later */ 383 void
··· 364 smbhash(p24 + 16, c8, p21 + 14, 1); 365 } 366 367 + #if 0 /* currently unsued */ 368 + static void 369 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) 370 { 371 smbhash(out, in, p14, 0); 372 smbhash(out + 8, in + 8, p14 + 7, 0); 373 } 374 375 + static void 376 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out) 377 { 378 smbhash(out, in, p14, 1); 379 smbhash(out + 8, in + 8, p14 + 7, 1); 380 } 381 /* these routines are currently unneeded, but may be 382 needed later */ 383 void
+6 -5
fs/cifs/smbencrypt.c
··· 51 52 void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 53 void E_md4hash(const unsigned char *passwd, unsigned char *p16); 54 - void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]); 55 static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, 56 unsigned char p24[24]); 57 - void NTLMSSPOWFencrypt(unsigned char passwd[8], 58 - unsigned char *ntlmchalresp, unsigned char p24[24]); 59 void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 60 61 /* ··· 141 memset(wpwd,0,129 * 2); 142 } 143 144 /* Does both the NT and LM owfs of a user's password */ 145 - void 146 nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) 147 { 148 char passwd[514]; ··· 169 /* clear out local copy of user's password (just being paranoid). */ 170 memset(passwd, '\0', sizeof (passwd)); 171 } 172 173 /* Does the NTLMv2 owfs of a user's password */ 174 #if 0 /* function not needed yet - but will be soon */ ··· 222 } 223 224 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 225 - void 226 NTLMSSPOWFencrypt(unsigned char passwd[8], 227 unsigned char *ntlmchalresp, unsigned char p24[24]) 228 { ··· 235 236 E_P24(p21, ntlmchalresp, p24); 237 } 238 239 /* Does the NT MD4 hash then des encryption. */ 240
··· 51 52 void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 53 void E_md4hash(const unsigned char *passwd, unsigned char *p16); 54 static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, 55 unsigned char p24[24]); 56 void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 57 58 /* ··· 144 memset(wpwd,0,129 * 2); 145 } 146 147 + #if 0 /* currently unused */ 148 /* Does both the NT and LM owfs of a user's password */ 149 + static void 150 nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) 151 { 152 char passwd[514]; ··· 171 /* clear out local copy of user's password (just being paranoid). */ 172 memset(passwd, '\0', sizeof (passwd)); 173 } 174 + #endif 175 176 /* Does the NTLMv2 owfs of a user's password */ 177 #if 0 /* function not needed yet - but will be soon */ ··· 223 } 224 225 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 226 + #if 0 /* currently unused */ 227 + static void 228 NTLMSSPOWFencrypt(unsigned char passwd[8], 229 unsigned char *ntlmchalresp, unsigned char p24[24]) 230 { ··· 235 236 E_P24(p21, ntlmchalresp, p24); 237 } 238 + #endif 239 240 /* Does the NT MD4 hash then des encryption. */ 241