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