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