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
This commit is contained in:
Коммит
12e36b2f41
|
@ -1986,7 +1986,7 @@ config CIFS_EXPERIMENTAL
|
|||
config CIFS_UPCALL
|
||||
bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
|
||||
depends on CIFS_EXPERIMENTAL
|
||||
select CONNECTOR
|
||||
depends on CONNECTOR
|
||||
help
|
||||
Enables an upcall mechanism for CIFS which will be used to contact
|
||||
userspace helper utilities to provide SPNEGO packaged Kerberos
|
||||
|
|
|
@ -31,8 +31,8 @@ struct cifs_sid {
|
|||
} __attribute__((packed));
|
||||
|
||||
/* everyone */
|
||||
extern const struct cifs_sid sid_everyone;
|
||||
/* extern const struct cifs_sid sid_everyone;*/
|
||||
/* group users */
|
||||
extern const struct cifs_sid sid_user;
|
||||
/* extern const struct cifs_sid sid_user;*/
|
||||
|
||||
#endif /* _CIFSACL_H */
|
||||
|
|
|
@ -27,8 +27,6 @@ extern void mdfour(unsigned char *out, unsigned char *in, int n);
|
|||
/* smbdes.c */
|
||||
extern void E_P16(unsigned char *p14, unsigned char *p16);
|
||||
extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
|
||||
extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
|
||||
extern void E_old_pw_hash(unsigned char *, unsigned char *, unsigned char *);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ extern struct task_struct * oplockThread; /* remove sparse warning */
|
|||
struct task_struct * oplockThread = NULL;
|
||||
extern struct task_struct * dnotifyThread; /* remove sparse warning */
|
||||
struct task_struct * dnotifyThread = NULL;
|
||||
static struct super_operations cifs_super_ops;
|
||||
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
|
||||
module_param(CIFSMaxBufSize, int, 0);
|
||||
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)
|
|||
/* Only need to call the old QFSInfo if failed
|
||||
on newer one */
|
||||
if(rc)
|
||||
rc = CIFSSMBQFSInfo(xid, pTcon, buf);
|
||||
if(pTcon->ses->capabilities & CAP_NT_SMBS)
|
||||
rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
|
||||
|
||||
/* Old Windows servers do not support level 103, retry with level
|
||||
one if old server failed the previous call */
|
||||
/* Some old Windows servers also do not support level 103, retry with
|
||||
older level one if old server failed the previous call or we
|
||||
bypassed it because we detected that this was an older LANMAN sess */
|
||||
if(rc)
|
||||
rc = SMBOldQFSInfo(xid, pTcon, buf);
|
||||
/*
|
||||
|
@ -435,13 +438,21 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
|
||||
{
|
||||
/* BB FIXME */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cifs_remount(struct super_block *sb, int *flags, char *data)
|
||||
{
|
||||
*flags |= MS_NODIRATIME;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct super_operations cifs_super_ops = {
|
||||
static struct super_operations cifs_super_ops = {
|
||||
.read_inode = cifs_read_inode,
|
||||
.put_super = cifs_put_super,
|
||||
.statfs = cifs_statfs,
|
||||
|
@ -454,6 +465,9 @@ struct super_operations cifs_super_ops = {
|
|||
.show_options = cifs_show_options,
|
||||
.umount_begin = cifs_umount_begin,
|
||||
.remount_fs = cifs_remount,
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
.show_stats = cifs_show_stats,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -495,7 +509,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
|||
static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
|
||||
{
|
||||
/* origin == SEEK_END => we must revalidate the cached file length */
|
||||
if (origin == 2) {
|
||||
if (origin == SEEK_END) {
|
||||
int retval = cifs_revalidate(file->f_dentry);
|
||||
if (retval < 0)
|
||||
return (loff_t)retval;
|
||||
|
@ -903,7 +917,7 @@ init_cifs(void)
|
|||
#ifdef CONFIG_PROC_FS
|
||||
cifs_proc_init();
|
||||
#endif
|
||||
INIT_LIST_HEAD(&GlobalServerList); /* BB not implemented yet */
|
||||
/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */
|
||||
INIT_LIST_HEAD(&GlobalSMBSessionList);
|
||||
INIT_LIST_HEAD(&GlobalTreeConnectionList);
|
||||
INIT_LIST_HEAD(&GlobalOplock_Q);
|
||||
|
@ -931,6 +945,7 @@ init_cifs(void)
|
|||
GlobalCurrentXid = 0;
|
||||
GlobalTotalActiveXid = 0;
|
||||
GlobalMaxActiveXid = 0;
|
||||
memset(Local_System_Name, 0, 15);
|
||||
rwlock_init(&GlobalSMBSeslock);
|
||||
spin_lock_init(&GlobalMid_Lock);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ extern const struct address_space_operations cifs_addr_ops;
|
|||
extern const struct address_space_operations cifs_addr_ops_smallbuf;
|
||||
|
||||
/* Functions related to super block operations */
|
||||
extern struct super_operations cifs_super_ops;
|
||||
/* extern struct super_operations cifs_super_ops;*/
|
||||
extern void cifs_read_inode(struct inode *);
|
||||
extern void cifs_delete_inode(struct inode *);
|
||||
/* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
|
||||
|
|
|
@ -153,7 +153,7 @@ struct TCP_Server_Info {
|
|||
char sessid[4]; /* unique token id for this session */
|
||||
/* (returned on Negotiate */
|
||||
int capabilities; /* allow selective disabling of caps by smb sess */
|
||||
__u16 timeZone;
|
||||
int timeAdj; /* Adjust for difference in server time zone in sec */
|
||||
__u16 CurrentMid; /* multiplex id - rotating counter */
|
||||
char cryptKey[CIFS_CRYPTO_KEY_SIZE];
|
||||
/* 16th byte of RFC1001 workstation name is always null */
|
||||
|
@ -203,9 +203,14 @@ struct cifsSesInfo {
|
|||
char * domainName;
|
||||
char * password;
|
||||
};
|
||||
/* session flags */
|
||||
/* no more than one of the following three session flags may be set */
|
||||
#define CIFS_SES_NT4 1
|
||||
|
||||
#define CIFS_SES_OS2 2
|
||||
#define CIFS_SES_W9X 4
|
||||
/* following flag is set for old servers such as OS2 (and Win95?)
|
||||
which do not negotiate NTLM or POSIX dialects, but instead
|
||||
negotiate one of the older LANMAN dialects */
|
||||
#define CIFS_SES_LANMAN 8
|
||||
/*
|
||||
* there is one of these for each connection to a resource on a particular
|
||||
* session
|
||||
|
@ -512,7 +517,8 @@ require use of the stronger protocol */
|
|||
* This list helps improve performance and eliminate the messages indicating
|
||||
* that we had a communications error talking to the server in this list.
|
||||
*/
|
||||
GLOBAL_EXTERN struct servers_not_supported *NotSuppList; /*@z4a */
|
||||
/* Feature not supported */
|
||||
/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */
|
||||
|
||||
/*
|
||||
* The following is a hash table of all the users we know about.
|
||||
|
@ -568,7 +574,6 @@ GLOBAL_EXTERN unsigned int lookupCacheEnabled;
|
|||
GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
|
||||
with more secure ntlmssp2 challenge/resp */
|
||||
GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */
|
||||
GLOBAL_EXTERN unsigned int secFlags;
|
||||
GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
|
||||
GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */
|
||||
GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
#define LANMAN_PROT 0
|
||||
#define CIFS_PROT 1
|
||||
#define LANMAN2_PROT 1
|
||||
#define CIFS_PROT 2
|
||||
#else
|
||||
#define CIFS_PROT 0
|
||||
#endif
|
||||
|
@ -408,6 +409,8 @@ typedef struct negotiate_req {
|
|||
|
||||
/* Dialect index is 13 for LANMAN */
|
||||
|
||||
#define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */
|
||||
|
||||
typedef struct lanman_neg_rsp {
|
||||
struct smb_hdr hdr; /* wct = 13 */
|
||||
__le16 DialectIndex;
|
||||
|
@ -417,7 +420,10 @@ typedef struct lanman_neg_rsp {
|
|||
__le16 MaxNumberVcs;
|
||||
__le16 RawMode;
|
||||
__le32 SessionKey;
|
||||
__le32 ServerTime;
|
||||
struct {
|
||||
__le16 Time;
|
||||
__le16 Date;
|
||||
} __attribute__((packed)) SrvTime;
|
||||
__le16 ServerTimeZone;
|
||||
__le16 EncryptionKeyLength;
|
||||
__le16 Reserved;
|
||||
|
@ -674,7 +680,7 @@ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
|
|||
typedef struct smb_com_close_req {
|
||||
struct smb_hdr hdr; /* wct = 3 */
|
||||
__u16 FileID;
|
||||
__u32 LastWriteTime; /* should be zero */
|
||||
__u32 LastWriteTime; /* should be zero or -1 */
|
||||
__u16 ByteCount; /* 0 */
|
||||
} __attribute__((packed)) CLOSE_REQ;
|
||||
|
||||
|
|
|
@ -50,12 +50,12 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
|
|||
extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
|
||||
struct kvec *, int /* nvec to send */,
|
||||
int * /* type of buf returned */ , const int long_op);
|
||||
extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *,
|
||||
extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
|
||||
struct cifsTconInfo *,
|
||||
struct smb_hdr * /* input */ ,
|
||||
struct smb_hdr * /* out */ ,
|
||||
int * /* bytes returned */);
|
||||
extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
|
||||
extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
|
||||
extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
|
||||
extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
|
||||
extern int is_size_safe_to_change(struct cifsInodeInfo *);
|
||||
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
|
||||
|
@ -80,6 +80,9 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
|
|||
extern void DeleteOplockQEntry(struct oplock_q_entry *);
|
||||
extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
|
||||
extern u64 cifs_UnixTimeToNT(struct timespec);
|
||||
extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
|
||||
extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
|
||||
|
||||
extern int cifs_get_inode_info(struct inode **pinode,
|
||||
const unsigned char *search_path,
|
||||
FILE_ALL_INFO * pfile_info,
|
||||
|
@ -116,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
|
|||
extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO * findData,
|
||||
int legacy /* whether to use old info level */,
|
||||
const struct nls_table *nls_codepage, int remap);
|
||||
extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName,
|
||||
|
@ -279,8 +283,6 @@ extern void sesInfoFree(struct cifsSesInfo *);
|
|||
extern struct cifsTconInfo *tconInfoAlloc(void);
|
||||
extern void tconInfoFree(struct cifsTconInfo *);
|
||||
|
||||
extern int cifs_reconnect(struct TCP_Server_Info *server);
|
||||
|
||||
extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
|
||||
extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
|
||||
__u32 *);
|
||||
|
|
|
@ -46,6 +46,7 @@ static struct {
|
|||
} protocols[] = {
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
{LANMAN_PROT, "\2LM1.2X002"},
|
||||
{LANMAN2_PROT, "\2LANMAN2.1"},
|
||||
#endif /* weak password hashing for legacy clients */
|
||||
{CIFS_PROT, "\2NT LM 0.12"},
|
||||
{POSIX_PROT, "\2POSIX 2"},
|
||||
|
@ -58,6 +59,7 @@ static struct {
|
|||
} protocols[] = {
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
{LANMAN_PROT, "\2LM1.2X002"},
|
||||
{LANMAN2_PROT, "\2LANMAN2.1"},
|
||||
#endif /* weak password hashing for legacy clients */
|
||||
{CIFS_PROT, "\2NT LM 0.12"},
|
||||
{BAD_PROT, "\2"}
|
||||
|
@ -67,13 +69,13 @@ static struct {
|
|||
/* define the number of elements in the cifs dialect array */
|
||||
#ifdef CONFIG_CIFS_POSIX
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
#define CIFS_NUM_PROT 3
|
||||
#define CIFS_NUM_PROT 4
|
||||
#else
|
||||
#define CIFS_NUM_PROT 2
|
||||
#endif /* CIFS_WEAK_PW_HASH */
|
||||
#else /* not posix */
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
#define CIFS_NUM_PROT 2
|
||||
#define CIFS_NUM_PROT 3
|
||||
#else
|
||||
#define CIFS_NUM_PROT 1
|
||||
#endif /* CONFIG_CIFS_WEAK_PW_HASH */
|
||||
|
@ -446,7 +448,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
goto neg_err_exit;
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
} else if((pSMBr->hdr.WordCount == 13)
|
||||
&& (pSMBr->DialectIndex == LANMAN_PROT)) {
|
||||
&& ((pSMBr->DialectIndex == LANMAN_PROT)
|
||||
|| (pSMBr->DialectIndex == LANMAN2_PROT))) {
|
||||
__s16 tmp;
|
||||
struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr;
|
||||
|
||||
if((secFlags & CIFSSEC_MAY_LANMAN) ||
|
||||
|
@ -472,12 +476,44 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
server->maxRw = 0;/* we do not need to use raw anyway */
|
||||
server->capabilities = CAP_MPX_MODE;
|
||||
}
|
||||
server->timeZone = le16_to_cpu(rsp->ServerTimeZone);
|
||||
tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
|
||||
if (tmp == -1) {
|
||||
/* OS/2 often does not set timezone therefore
|
||||
* we must use server time to calc time zone.
|
||||
* Could deviate slightly from the right zone.
|
||||
* Smallest defined timezone difference is 15 minutes
|
||||
* (i.e. Nepal). Rounding up/down is done to match
|
||||
* this requirement.
|
||||
*/
|
||||
int val, seconds, remain, result;
|
||||
struct timespec ts, utc;
|
||||
utc = CURRENT_TIME;
|
||||
ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
|
||||
le16_to_cpu(rsp->SrvTime.Time));
|
||||
cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d",
|
||||
(int)ts.tv_sec, (int)utc.tv_sec,
|
||||
(int)(utc.tv_sec - ts.tv_sec)));
|
||||
val = (int)(utc.tv_sec - ts.tv_sec);
|
||||
seconds = val < 0 ? -val : val;
|
||||
result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
|
||||
remain = seconds % MIN_TZ_ADJ;
|
||||
if(remain >= (MIN_TZ_ADJ / 2))
|
||||
result += MIN_TZ_ADJ;
|
||||
if(val < 0)
|
||||
result = - result;
|
||||
server->timeAdj = result;
|
||||
} else {
|
||||
server->timeAdj = (int)tmp;
|
||||
server->timeAdj *= 60; /* also in seconds */
|
||||
}
|
||||
cFYI(1,("server->timeAdj: %d seconds", server->timeAdj));
|
||||
|
||||
|
||||
/* BB get server time for time conversions and add
|
||||
code to use it and timezone since this is not UTC */
|
||||
|
||||
if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
|
||||
if (rsp->EncryptionKeyLength ==
|
||||
cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
|
||||
memcpy(server->cryptKey, rsp->EncryptionKey,
|
||||
CIFS_CRYPTO_KEY_SIZE);
|
||||
} else if (server->secMode & SECMODE_PW_ENCRYPT) {
|
||||
|
@ -531,7 +567,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
cFYI(0, ("Max buf = %d", ses->server->maxBuf));
|
||||
GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
|
||||
server->capabilities = le32_to_cpu(pSMBr->Capabilities);
|
||||
server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);
|
||||
server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
|
||||
server->timeAdj *= 60;
|
||||
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
|
||||
memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
|
||||
CIFS_CRYPTO_KEY_SIZE);
|
||||
|
@ -1617,7 +1654,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
|
|||
pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
|
||||
|
||||
pSMB->FileID = (__u16) smb_file_id;
|
||||
pSMB->LastWriteTime = 0;
|
||||
pSMB->LastWriteTime = 0xFFFFFFFF;
|
||||
pSMB->ByteCount = 0;
|
||||
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
||||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||
|
@ -2773,9 +2810,11 @@ GetExtAttrOut:
|
|||
|
||||
|
||||
/* security id for everyone */
|
||||
const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
|
||||
const static struct cifs_sid sid_everyone =
|
||||
{1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
|
||||
/* group users */
|
||||
const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
|
||||
const static struct cifs_sid sid_user =
|
||||
{1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
|
||||
|
||||
/* Convert CIFS ACL to POSIX form */
|
||||
static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
|
||||
|
@ -2856,7 +2895,6 @@ qsec_out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Legacy Query Path Information call for lookup to old servers such
|
||||
as Win9x/WinME */
|
||||
int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
||||
|
@ -2898,7 +2936,16 @@ QInfRetry:
|
|||
if (rc) {
|
||||
cFYI(1, ("Send error in QueryInfo = %d", rc));
|
||||
} else if (pFinfo) { /* decode response */
|
||||
struct timespec ts;
|
||||
__u32 time = le32_to_cpu(pSMBr->last_write_time);
|
||||
/* BB FIXME - add time zone adjustment BB */
|
||||
memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
|
||||
ts.tv_nsec = 0;
|
||||
ts.tv_sec = time;
|
||||
/* decode time fields */
|
||||
pFinfo->ChangeTime = cifs_UnixTimeToNT(ts);
|
||||
pFinfo->LastWriteTime = pFinfo->ChangeTime;
|
||||
pFinfo->LastAccessTime = 0;
|
||||
pFinfo->AllocationSize =
|
||||
cpu_to_le64(le32_to_cpu(pSMBr->size));
|
||||
pFinfo->EndOfFile = pFinfo->AllocationSize;
|
||||
|
@ -2922,6 +2969,7 @@ int
|
|||
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO * pFindData,
|
||||
int legacy /* old style infolevel */,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
/* level 263 SMB_QUERY_FILE_ALL_INFO */
|
||||
|
@ -2970,7 +3018,10 @@ QPathInfoRetry:
|
|||
byte_count = params + 1 /* pad */ ;
|
||||
pSMB->TotalParameterCount = cpu_to_le16(params);
|
||||
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
||||
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
|
||||
if(legacy)
|
||||
pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
|
||||
else
|
||||
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
|
||||
pSMB->Reserved4 = 0;
|
||||
pSMB->hdr.smb_buf_length += byte_count;
|
||||
pSMB->ByteCount = cpu_to_le16(byte_count);
|
||||
|
@ -2982,13 +3033,24 @@ QPathInfoRetry:
|
|||
} else { /* decode response */
|
||||
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
||||
|
||||
if (rc || (pSMBr->ByteCount < 40))
|
||||
if (rc) /* BB add auto retry on EOPNOTSUPP? */
|
||||
rc = -EIO;
|
||||
else if (!legacy && (pSMBr->ByteCount < 40))
|
||||
rc = -EIO; /* bad smb */
|
||||
else if(legacy && (pSMBr->ByteCount < 24))
|
||||
rc = -EIO; /* 24 or 26 expected but we do not read last field */
|
||||
else if (pFindData){
|
||||
int size;
|
||||
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
||||
if(legacy) /* we do not read the last field, EAsize, fortunately
|
||||
since it varies by subdialect and on Set vs. Get, is
|
||||
two bytes or 4 bytes depending but we don't care here */
|
||||
size = sizeof(FILE_INFO_STANDARD);
|
||||
else
|
||||
size = sizeof(FILE_ALL_INFO);
|
||||
memcpy((char *) pFindData,
|
||||
(char *) &pSMBr->hdr.Protocol +
|
||||
data_offset, sizeof (FILE_ALL_INFO));
|
||||
data_offset, size);
|
||||
} else
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
|
@ -3613,6 +3675,14 @@ getDFSRetry:
|
|||
strncpy(pSMB->RequestFileName, searchName, name_len);
|
||||
}
|
||||
|
||||
if(ses->server) {
|
||||
if(ses->server->secMode &
|
||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
||||
}
|
||||
|
||||
pSMB->hdr.Uid = ses->Suid;
|
||||
|
||||
params = 2 /* level */ + name_len /*includes null */ ;
|
||||
pSMB->TotalDataCount = 0;
|
||||
pSMB->DataCount = 0;
|
||||
|
|
|
@ -109,7 +109,7 @@ static int ipv6_connect(struct sockaddr_in6 *psin_server,
|
|||
* wake up waiters on reconnection? - (not needed currently)
|
||||
*/
|
||||
|
||||
int
|
||||
static int
|
||||
cifs_reconnect(struct TCP_Server_Info *server)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -771,13 +771,18 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
|
|||
separator[0] = ',';
|
||||
separator[1] = 0;
|
||||
|
||||
memset(vol->source_rfc1001_name,0x20,15);
|
||||
for(i=0;i < strnlen(utsname()->nodename,15);i++) {
|
||||
/* does not have to be a perfect mapping since the field is
|
||||
informational, only used for servers that do not support
|
||||
port 445 and it can be overridden at mount time */
|
||||
vol->source_rfc1001_name[i] =
|
||||
toupper(utsname()->nodename[i]);
|
||||
if (Local_System_Name[0] != 0)
|
||||
memcpy(vol->source_rfc1001_name, Local_System_Name,15);
|
||||
else {
|
||||
char *nodename = utsname()->nodename;
|
||||
int n = strnlen(nodename,15);
|
||||
memset(vol->source_rfc1001_name,0x20,15);
|
||||
for(i=0 ; i < n ; i++) {
|
||||
/* does not have to be perfect mapping since field is
|
||||
informational, only used for servers that do not support
|
||||
port 445 and it can be overridden at mount time */
|
||||
vol->source_rfc1001_name[i] = toupper(nodename[i]);
|
||||
}
|
||||
}
|
||||
vol->source_rfc1001_name[15] = 0;
|
||||
/* null target name indicates to use *SMBSERVR default called name
|
||||
|
@ -3215,7 +3220,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
|
|||
}
|
||||
/* else do not bother copying these informational fields */
|
||||
}
|
||||
if(smb_buffer_response->WordCount == 3)
|
||||
if((smb_buffer_response->WordCount == 3) ||
|
||||
(smb_buffer_response->WordCount == 7))
|
||||
/* field is in same location */
|
||||
tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
|
||||
else
|
||||
tcon->Flags = 0;
|
||||
|
@ -3312,19 +3319,21 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
|||
first_time = 1;
|
||||
}
|
||||
if (!rc) {
|
||||
pSesInfo->flags = 0;
|
||||
pSesInfo->capabilities = pSesInfo->server->capabilities;
|
||||
if(linuxExtEnabled == 0)
|
||||
pSesInfo->capabilities &= (~CAP_UNIX);
|
||||
/* pSesInfo->sequence_number = 0;*/
|
||||
cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
|
||||
cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
|
||||
pSesInfo->server->secMode,
|
||||
pSesInfo->server->capabilities,
|
||||
pSesInfo->server->timeZone));
|
||||
pSesInfo->server->timeAdj));
|
||||
if(experimEnabled < 2)
|
||||
rc = CIFS_SessSetup(xid, pSesInfo,
|
||||
first_time, nls_info);
|
||||
else if (extended_security
|
||||
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
|
||||
&& (pSesInfo->capabilities
|
||||
& CAP_EXTENDED_SECURITY)
|
||||
&& (pSesInfo->server->secType == NTLMSSP)) {
|
||||
rc = -EOPNOTSUPP;
|
||||
} else if (extended_security
|
||||
|
@ -3338,7 +3347,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
|||
if (!rc) {
|
||||
if(ntlmv2_flag) {
|
||||
char * v2_response;
|
||||
cFYI(1,("Can use more secure NTLM version 2 password hash"));
|
||||
cFYI(1,("more secure NTLM ver2 hash"));
|
||||
if(CalcNTLMv2_partial_mac_key(pSesInfo,
|
||||
nls_info)) {
|
||||
rc = -ENOMEM;
|
||||
|
|
|
@ -337,6 +337,7 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
pfindData = (FILE_ALL_INFO *)buf;
|
||||
/* could do find first instead but this returns more info */
|
||||
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
|
||||
0 /* not legacy */,
|
||||
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
/* BB optimize code so we do not make the above call
|
||||
|
@ -384,8 +385,10 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
/* get new inode */
|
||||
if (*pinode == NULL) {
|
||||
*pinode = new_inode(sb);
|
||||
if (*pinode == NULL)
|
||||
if (*pinode == NULL) {
|
||||
kfree(buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Is an i_ino of zero legal? Can we use that to check
|
||||
if the server supports returning inode numbers? Are
|
||||
there other sanity checks we can use to ensure that
|
||||
|
@ -431,8 +434,11 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
|
||||
|
||||
/* Linux can not store file creation time so ignore it */
|
||||
inode->i_atime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
|
||||
if(pfindData->LastAccessTime)
|
||||
inode->i_atime = cifs_NTtimeToUnix
|
||||
(le64_to_cpu(pfindData->LastAccessTime));
|
||||
else /* do not need to use current_fs_time - time not stored */
|
||||
inode->i_atime = CURRENT_TIME;
|
||||
inode->i_mtime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
|
||||
inode->i_ctime =
|
||||
|
|
|
@ -254,7 +254,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
|
|||
tmpbuffer,
|
||||
len - 1,
|
||||
cifs_sb->local_nls);
|
||||
else {
|
||||
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||
cERROR(1,("SFU style symlinks not implemented yet"));
|
||||
/* add open and read as in fs/cifs/inode.c */
|
||||
|
||||
} else {
|
||||
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
|
||||
OPEN_REPARSE_POINT,&fid, &oplock, NULL,
|
||||
cifs_sb->local_nls,
|
||||
|
|
|
@ -252,10 +252,11 @@ MD5Transform(__u32 buf[4], __u32 const in[16])
|
|||
buf[3] += d;
|
||||
}
|
||||
|
||||
#if 0 /* currently unused */
|
||||
/***********************************************************************
|
||||
the rfc 2104 version of hmac_md5 initialisation.
|
||||
***********************************************************************/
|
||||
void
|
||||
static void
|
||||
hmac_md5_init_rfc2104(unsigned char *key, int key_len,
|
||||
struct HMACMD5Context *ctx)
|
||||
{
|
||||
|
@ -289,6 +290,7 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len,
|
|||
MD5Init(&ctx->ctx);
|
||||
MD5Update(&ctx->ctx, ctx->k_ipad, 64);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
the microsoft version of hmac_md5 initialisation.
|
||||
|
@ -350,7 +352,8 @@ hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)
|
|||
single function to calculate an HMAC MD5 digest from data.
|
||||
use the microsoft hmacmd5 init method because the key is 16 bytes.
|
||||
************************************************************/
|
||||
void
|
||||
#if 0 /* currently unused */
|
||||
static void
|
||||
hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
|
||||
unsigned char *digest)
|
||||
{
|
||||
|
@ -361,3 +364,4 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
|
|||
}
|
||||
hmac_md5_final(digest, &ctx);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,12 +27,12 @@ void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
|||
|
||||
/* The following definitions come from lib/hmacmd5.c */
|
||||
|
||||
void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
|
||||
struct HMACMD5Context *ctx);
|
||||
/* void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
|
||||
struct HMACMD5Context *ctx);*/
|
||||
void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
|
||||
struct HMACMD5Context *ctx);
|
||||
void hmac_md5_update(const unsigned char *text, int text_len,
|
||||
struct HMACMD5Context *ctx);
|
||||
void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
|
||||
void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
|
||||
unsigned char *digest);
|
||||
/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
|
||||
unsigned char *digest);*/
|
||||
|
|
|
@ -389,7 +389,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
|
|||
return;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
checkSMBhdr(struct smb_hdr *smb, __u16 mid)
|
||||
{
|
||||
/* Make sure that this really is an SMB, that it is a response,
|
||||
|
@ -418,26 +418,42 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
|
|||
}
|
||||
|
||||
int
|
||||
checkSMB(struct smb_hdr *smb, __u16 mid, int length)
|
||||
checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
|
||||
{
|
||||
__u32 len = smb->smb_buf_length;
|
||||
__u32 clc_len; /* calculated length */
|
||||
cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
|
||||
if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
|
||||
(len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
|
||||
if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
|
||||
if (((unsigned int)length >=
|
||||
sizeof (struct smb_hdr) - 1)
|
||||
|
||||
if (length < 2 + sizeof (struct smb_hdr)) {
|
||||
if ((length >= sizeof (struct smb_hdr) - 1)
|
||||
&& (smb->Status.CifsError != 0)) {
|
||||
smb->WordCount = 0;
|
||||
/* some error cases do not return wct and bcc */
|
||||
smb->WordCount = 0;
|
||||
/* some error cases do not return wct and bcc */
|
||||
return 0;
|
||||
} else if ((length == sizeof(struct smb_hdr) + 1) &&
|
||||
(smb->WordCount == 0)) {
|
||||
char * tmp = (char *)smb;
|
||||
/* Need to work around a bug in two servers here */
|
||||
/* First, check if the part of bcc they sent was zero */
|
||||
if (tmp[sizeof(struct smb_hdr)] == 0) {
|
||||
/* some servers return only half of bcc
|
||||
* on simple responses (wct, bcc both zero)
|
||||
* in particular have seen this on
|
||||
* ulogoffX and FindClose. This leaves
|
||||
* one byte of bcc potentially unitialized
|
||||
*/
|
||||
/* zero rest of bcc */
|
||||
tmp[sizeof(struct smb_hdr)+1] = 0;
|
||||
return 0;
|
||||
} else {
|
||||
cERROR(1, ("Length less than smb header size"));
|
||||
}
|
||||
cERROR(1,("rcvd invalid byte count (bcc)"));
|
||||
} else {
|
||||
cERROR(1, ("Length less than smb header size"));
|
||||
}
|
||||
if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
|
||||
cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
|
||||
return 1;
|
||||
}
|
||||
if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
|
||||
cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
|
||||
smb->Mid));
|
||||
return 1;
|
||||
}
|
||||
|
@ -446,7 +462,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
|
|||
return 1;
|
||||
clc_len = smbCalcSize_LE(smb);
|
||||
|
||||
if(4 + len != (unsigned int)length) {
|
||||
if(4 + len != length) {
|
||||
cERROR(1, ("Length read does not match RFC1001 length %d",len));
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -909,3 +909,61 @@ cifs_UnixTimeToNT(struct timespec t)
|
|||
/* Convert to 100ns intervals and then add the NTFS time offset. */
|
||||
return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
|
||||
}
|
||||
|
||||
static int total_days_of_prev_months[] =
|
||||
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||
|
||||
|
||||
__le64 cnvrtDosCifsTm(__u16 date, __u16 time)
|
||||
{
|
||||
return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time)));
|
||||
}
|
||||
|
||||
struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
|
||||
{
|
||||
struct timespec ts;
|
||||
int sec, min, days, month, year;
|
||||
SMB_TIME * st = (SMB_TIME *)&time;
|
||||
SMB_DATE * sd = (SMB_DATE *)&date;
|
||||
|
||||
cFYI(1,("date %d time %d",date, time));
|
||||
|
||||
sec = 2 * st->TwoSeconds;
|
||||
min = st->Minutes;
|
||||
if((sec > 59) || (min > 59))
|
||||
cERROR(1,("illegal time min %d sec %d", min, sec));
|
||||
sec += (min * 60);
|
||||
sec += 60 * 60 * st->Hours;
|
||||
if(st->Hours > 24)
|
||||
cERROR(1,("illegal hours %d",st->Hours));
|
||||
days = sd->Day;
|
||||
month = sd->Month;
|
||||
if((days > 31) || (month > 12))
|
||||
cERROR(1,("illegal date, month %d day: %d", month, days));
|
||||
month -= 1;
|
||||
days += total_days_of_prev_months[month];
|
||||
days += 3652; /* account for difference in days between 1980 and 1970 */
|
||||
year = sd->Year;
|
||||
days += year * 365;
|
||||
days += (year/4); /* leap year */
|
||||
/* generalized leap year calculation is more complex, ie no leap year
|
||||
for years/100 except for years/400, but since the maximum number for DOS
|
||||
year is 2**7, the last year is 1980+127, which means we need only
|
||||
consider 2 special case years, ie the years 2000 and 2100, and only
|
||||
adjust for the lack of leap year for the year 2100, as 2000 was a
|
||||
leap year (divisable by 400) */
|
||||
if(year >= 120) /* the year 2100 */
|
||||
days = days - 1; /* do not count leap year for the year 2100 */
|
||||
|
||||
/* adjust for leap year where we are still before leap day */
|
||||
if(year != 120)
|
||||
days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
|
||||
sec += 24 * 60 * 60 * days;
|
||||
|
||||
ts.tv_sec = sec;
|
||||
|
||||
/* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */
|
||||
|
||||
ts.tv_nsec = 0;
|
||||
return ts;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
|
||||
{
|
||||
if((tcon) && (tcon->ses) && (tcon->ses->server)) {
|
||||
inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
|
||||
inode->i_mtime.tv_sec += tcon->ses->server->timeAdj;
|
||||
inode->i_atime.tv_sec += tcon->ses->server->timeAdj;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
||||
char * buf, int *pobject_type, int isNewInode)
|
||||
{
|
||||
|
@ -135,16 +146,23 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
|||
tmp_inode->i_ctime =
|
||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
|
||||
} else { /* legacy, OS2 and DOS style */
|
||||
/* struct timespec ts;*/
|
||||
FIND_FILE_STANDARD_INFO * pfindData =
|
||||
(FIND_FILE_STANDARD_INFO *)buf;
|
||||
|
||||
tmp_inode->i_mtime = cnvrtDosUnixTm(
|
||||
le16_to_cpu(pfindData->LastWriteDate),
|
||||
le16_to_cpu(pfindData->LastWriteTime));
|
||||
tmp_inode->i_atime = cnvrtDosUnixTm(
|
||||
le16_to_cpu(pfindData->LastAccessDate),
|
||||
le16_to_cpu(pfindData->LastAccessTime));
|
||||
tmp_inode->i_ctime = cnvrtDosUnixTm(
|
||||
le16_to_cpu(pfindData->LastWriteDate),
|
||||
le16_to_cpu(pfindData->LastWriteTime));
|
||||
AdjustForTZ(cifs_sb->tcon, tmp_inode);
|
||||
attr = le16_to_cpu(pfindData->Attributes);
|
||||
allocation_size = le32_to_cpu(pfindData->AllocationSize);
|
||||
end_of_file = le32_to_cpu(pfindData->DataSize);
|
||||
tmp_inode->i_atime = CURRENT_TIME;
|
||||
/* tmp_inode->i_mtime = BB FIXME - add dos time handling
|
||||
tmp_inode->i_ctime = 0; BB FIXME */
|
||||
|
||||
}
|
||||
|
||||
/* 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,
|
|||
filename = &pFindData->FileName[0];
|
||||
/* one byte length, no name conversion */
|
||||
len = (unsigned int)pFindData->FileNameLength;
|
||||
cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
|
||||
} else {
|
||||
cFYI(1,("Unknown findfirst level %d",level));
|
||||
return -EINVAL;
|
||||
|
|
|
@ -268,6 +268,10 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
|
|||
ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
|
||||
if(ses->serverOS)
|
||||
strncpy(ses->serverOS, bcc_ptr, len);
|
||||
if(strncmp(ses->serverOS, "OS/2",4) == 0) {
|
||||
cFYI(1,("OS/2 server"));
|
||||
ses->flags |= CIFS_SES_OS2;
|
||||
}
|
||||
|
||||
bcc_ptr += len + 1;
|
||||
bleft -= len + 1;
|
||||
|
@ -290,16 +294,11 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
|
|||
if(len > bleft)
|
||||
return rc;
|
||||
|
||||
if(ses->serverDomain)
|
||||
kfree(ses->serverDomain);
|
||||
|
||||
ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
|
||||
if(ses->serverOS)
|
||||
strncpy(ses->serverOS, bcc_ptr, len);
|
||||
|
||||
bcc_ptr += len + 1;
|
||||
bleft -= len + 1;
|
||||
|
||||
/* No domain field in LANMAN case. Domain is
|
||||
returned by old servers in the SMB negprot response */
|
||||
/* BB For newer servers which do not support Unicode,
|
||||
but thus do return domain here we could add parsing
|
||||
for it later, but it is not very important */
|
||||
cFYI(1,("ascii: bytes left %d",bleft));
|
||||
|
||||
return rc;
|
||||
|
@ -366,6 +365,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
|
|||
str_area = kmalloc(2000, GFP_KERNEL);
|
||||
bcc_ptr = str_area;
|
||||
|
||||
ses->flags &= ~CIFS_SES_LANMAN;
|
||||
|
||||
if(type == LANMAN) {
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
char lnm_session_key[CIFS_SESS_KEY_SIZE];
|
||||
|
@ -377,7 +378,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
|
|||
/* and copy into bcc */
|
||||
|
||||
calc_lanman_hash(ses, lnm_session_key);
|
||||
|
||||
ses->flags |= CIFS_SES_LANMAN;
|
||||
/* #ifdef CONFIG_CIFS_DEBUG2
|
||||
cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
|
||||
CIFS_SESS_KEY_SIZE);
|
||||
|
|
|
@ -364,20 +364,20 @@ E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
|
|||
smbhash(p24 + 16, c8, p21 + 14, 1);
|
||||
}
|
||||
|
||||
void
|
||||
#if 0 /* currently unsued */
|
||||
static void
|
||||
D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
|
||||
{
|
||||
smbhash(out, in, p14, 0);
|
||||
smbhash(out + 8, in + 8, p14 + 7, 0);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
|
||||
{
|
||||
smbhash(out, in, p14, 1);
|
||||
smbhash(out + 8, in + 8, p14 + 7, 1);
|
||||
}
|
||||
#if 0
|
||||
/* these routines are currently unneeded, but may be
|
||||
needed later */
|
||||
void
|
||||
|
|
|
@ -51,11 +51,8 @@
|
|||
|
||||
void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
|
||||
void E_md4hash(const unsigned char *passwd, unsigned char *p16);
|
||||
void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]);
|
||||
static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
|
||||
unsigned char p24[24]);
|
||||
void NTLMSSPOWFencrypt(unsigned char passwd[8],
|
||||
unsigned char *ntlmchalresp, unsigned char p24[24]);
|
||||
void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
|
||||
|
||||
/*
|
||||
|
@ -144,8 +141,9 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
|
|||
memset(wpwd,0,129 * 2);
|
||||
}
|
||||
|
||||
#if 0 /* currently unused */
|
||||
/* Does both the NT and LM owfs of a user's password */
|
||||
void
|
||||
static void
|
||||
nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
|
||||
{
|
||||
char passwd[514];
|
||||
|
@ -171,6 +169,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
|
|||
/* clear out local copy of user's password (just being paranoid). */
|
||||
memset(passwd, '\0', sizeof (passwd));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Does the NTLMv2 owfs of a user's password */
|
||||
#if 0 /* function not needed yet - but will be soon */
|
||||
|
@ -223,7 +222,8 @@ SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
|
|||
}
|
||||
|
||||
/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
|
||||
void
|
||||
#if 0 /* currently unused */
|
||||
static void
|
||||
NTLMSSPOWFencrypt(unsigned char passwd[8],
|
||||
unsigned char *ntlmchalresp, unsigned char p24[24])
|
||||
{
|
||||
|
@ -235,6 +235,7 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],
|
|||
|
||||
E_P24(p21, ntlmchalresp, p24);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Does the NT MD4 hash then des encryption. */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче