CIFS] Support for older servers which require plaintext passwords - part 2
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
Родитель
bdc4bf6e8a
Коммит
254e55ed03
|
@ -485,14 +485,34 @@ PacketSigningEnabled If set to one, cifs packet signing is enabled
|
|||
it. If set to two, cifs packet signing is
|
||||
required even if the server considers packet
|
||||
signing optional. (default 1)
|
||||
SecurityFlags Flags which control security negotiation and
|
||||
also packet signing. Authentication (may/must)
|
||||
flags (e.g. for NTLM and/or NTLMv2) may be combined with
|
||||
the signing flags. Specifying two different password
|
||||
hashing mechanisms (as "must use") on the other hand
|
||||
does not make much sense. Default flags are
|
||||
0x07007
|
||||
(NTLM, NTLMv2 and packet signing allowed). Maximum
|
||||
allowable flags if you want to allow mounts to servers
|
||||
using weaker password hashes is 0x37037 (lanman,
|
||||
plaintext, ntlm, ntlmv2, signing allowed):
|
||||
|
||||
may use packet signing 0x00001
|
||||
must use packet signing 0x01001
|
||||
may use NTLM (most common password hash) 0x00002
|
||||
must use NTLM 0x02002
|
||||
may use NTLMv2 0x00004
|
||||
must use NTLMv2 0x04004
|
||||
may use Kerberos security (not implemented yet) 0x00008
|
||||
must use Kerberos (not implemented yet) 0x08008
|
||||
may use lanman (weak) password hash 0x00010
|
||||
must use lanman password hash 0x10010
|
||||
may use plaintext passwords 0x00020
|
||||
must use plaintext passwords 0x20020
|
||||
(reserved for future packet encryption) 0x00040
|
||||
|
||||
cifsFYI If set to one, additional debug information is
|
||||
logged to the system error log. (default 0)
|
||||
ExtendedSecurity If set to one, SPNEGO session establishment
|
||||
is allowed which enables more advanced
|
||||
secure CIFS session establishment (default 0)
|
||||
NTLMV2Enabled If set to one, more secure password hashes
|
||||
are used when the server supports them and
|
||||
when kerberos is not negotiated (default 0)
|
||||
traceSMB If set to one, debug information is logged to the
|
||||
system error log with the start of smb requests
|
||||
and responses (default 0)
|
||||
|
|
|
@ -212,12 +212,12 @@ struct cifsTconInfo {
|
|||
struct list_head openFileList;
|
||||
struct semaphore tconSem;
|
||||
struct cifsSesInfo *ses; /* pointer to session associated with */
|
||||
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource (in ASCII not UTF) */
|
||||
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
|
||||
char *nativeFileSystem;
|
||||
__u16 tid; /* The 2 byte tree id */
|
||||
__u16 Flags; /* optional support bits */
|
||||
enum statusEnum tidStatus;
|
||||
atomic_t useCount; /* how many mounts (explicit or implicit) to this share */
|
||||
atomic_t useCount; /* how many explicit/implicit mounts to share */
|
||||
#ifdef CONFIG_CIFS_STATS
|
||||
atomic_t num_smbs_sent;
|
||||
atomic_t num_writes;
|
||||
|
@ -257,7 +257,7 @@ struct cifsTconInfo {
|
|||
spinlock_t stat_lock;
|
||||
#endif /* CONFIG_CIFS_STATS */
|
||||
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
|
||||
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */
|
||||
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
|
||||
FILE_SYSTEM_UNIX_INFO fsUnixInfo;
|
||||
unsigned retry:1;
|
||||
unsigned nocase:1;
|
||||
|
@ -308,7 +308,6 @@ struct cifsFileInfo {
|
|||
atomic_t wrtPending; /* handle in use - defer close */
|
||||
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
|
||||
char * search_resume_name; /* BB removeme BB */
|
||||
unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */
|
||||
struct cifs_search_info srch_inf;
|
||||
};
|
||||
|
||||
|
@ -523,16 +522,16 @@ GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */
|
|||
GLOBAL_EXTERN struct list_head GlobalOplock_Q;
|
||||
|
||||
GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */
|
||||
GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* Dir notify response queue */
|
||||
GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q;/* DirNotify response queue */
|
||||
|
||||
/*
|
||||
* Global transaction id (XID) information
|
||||
*/
|
||||
GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
|
||||
GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
|
||||
GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
|
||||
GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
|
||||
GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above and list operations */
|
||||
/* on midQ entries */
|
||||
GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */
|
||||
/* on midQ entries */
|
||||
GLOBAL_EXTERN char Local_System_Name[15];
|
||||
|
||||
/*
|
||||
|
@ -554,7 +553,7 @@ GLOBAL_EXTERN atomic_t smBufAllocCount;
|
|||
GLOBAL_EXTERN atomic_t midCount;
|
||||
|
||||
/* Misc globals */
|
||||
GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
|
||||
GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
|
||||
to be established on existing mount if we
|
||||
have the uid/password or Kerberos credential
|
||||
or equivalent for current user */
|
||||
|
|
|
@ -426,6 +426,10 @@ typedef struct lanman_neg_rsp {
|
|||
unsigned char EncryptionKey[1];
|
||||
} __attribute__((packed)) LANMAN_NEG_RSP;
|
||||
|
||||
#define READ_RAW_ENABLE 1
|
||||
#define WRITE_RAW_ENABLE 2
|
||||
#define RAW_ENABLE (READ_RAW_ENABLE | WRITE_RAW_ENABLE)
|
||||
|
||||
typedef struct negotiate_rsp {
|
||||
struct smb_hdr hdr; /* wct = 17 */
|
||||
__le16 DialectIndex;
|
||||
|
|
|
@ -411,8 +411,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
return rc;
|
||||
pSMB->hdr.Mid = GetNextMid(server);
|
||||
pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
|
||||
/* if (extended_security)
|
||||
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;*/
|
||||
if((extended_security & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
|
||||
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
|
||||
|
||||
count = 0;
|
||||
for(i=0;i<CIFS_NUM_PROT;i++) {
|
||||
|
@ -425,162 +425,171 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
|
||||
rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
|
||||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||
if (rc == 0) {
|
||||
cFYI(1,("Dialect: %d", pSMBr->DialectIndex));
|
||||
/* Check wct = 1 error case */
|
||||
if((pSMBr->hdr.WordCount < 13)
|
||||
|| (pSMBr->DialectIndex == BAD_PROT)) {
|
||||
/* core returns wct = 1, but we do not ask for
|
||||
core - otherwise it just comes when dialect
|
||||
index is -1 indicating we could not negotiate
|
||||
a common dialect */
|
||||
if (rc != 0)
|
||||
goto neg_err_exit;
|
||||
|
||||
cFYI(1,("Dialect: %d", pSMBr->DialectIndex));
|
||||
/* Check wct = 1 error case */
|
||||
if((pSMBr->hdr.WordCount < 13) || (pSMBr->DialectIndex == BAD_PROT)) {
|
||||
/* core returns wct = 1, but we do not ask for core - otherwise
|
||||
small wct just comes when dialect index is -1 indicating we
|
||||
could not negotiate a common dialect */
|
||||
rc = -EOPNOTSUPP;
|
||||
goto neg_err_exit;
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
} else if((pSMBr->hdr.WordCount == 13)
|
||||
&& (pSMBr->DialectIndex == LANMAN_PROT)) {
|
||||
struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr;
|
||||
|
||||
if((extended_security & CIFSSEC_MAY_LANMAN) ||
|
||||
(extended_security & CIFSSEC_MAY_PLNTXT))
|
||||
server->secType = LANMAN;
|
||||
else {
|
||||
cERROR(1, ("mount failed weak security disabled"
|
||||
" in /proc/fs/cifs/SecurityFlags"));
|
||||
rc = -EOPNOTSUPP;
|
||||
goto neg_err_exit;
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
} else if((pSMBr->hdr.WordCount == 13)
|
||||
&& (pSMBr->DialectIndex == LANMAN_PROT)) {
|
||||
struct lanman_neg_rsp * rsp =
|
||||
(struct lanman_neg_rsp *)pSMBr;
|
||||
|
||||
if((extended_security & CIFSSEC_MAY_LANMAN) ||
|
||||
(extended_security & CIFSSEC_MAY_PLNTXT))
|
||||
server->secType = LANMAN;
|
||||
else {
|
||||
cERROR(1, ("mount failed weak security disabled"
|
||||
" in /proc/fs/cifs/SecurityFlags"));
|
||||
rc = -EOPNOTSUPP;
|
||||
goto neg_err_exit;
|
||||
}
|
||||
server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
|
||||
server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
|
||||
server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
|
||||
}
|
||||
server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
|
||||
server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
|
||||
server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
|
||||
(__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
|
||||
GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey);
|
||||
/* even though we do not use raw we might as well set this
|
||||
accurately, in case we ever find a need for it */
|
||||
if((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
|
||||
server->maxRw = 0xFF00;
|
||||
server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
|
||||
} else {
|
||||
server->maxRw = 0;/* we do not need to use raw anyway */
|
||||
server->capabilities = CAP_MPX_MODE;
|
||||
}
|
||||
server->timeZone = le16_to_cpu(rsp->ServerTimeZone);
|
||||
|
||||
/* BB what do we do with raw mode? BB */
|
||||
server->timeZone = le16_to_cpu(rsp->ServerTimeZone);
|
||||
/* Do we have to set signing flags? no signing
|
||||
was available LANMAN - default should be ok */
|
||||
/* BB get server time for time conversions and add
|
||||
code to use it and timezone since this is not UTC */
|
||||
|
||||
/* BB FIXME set default dummy capabilities since
|
||||
they are not returned by the server in this dialect */
|
||||
if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
|
||||
memcpy(server->cryptKey, rsp->EncryptionKey,
|
||||
CIFS_CRYPTO_KEY_SIZE);
|
||||
} else if (server->secMode & SECMODE_PW_ENCRYPT) {
|
||||
rc = -EIO; /* need cryptkey unless plain text */
|
||||
goto neg_err_exit;
|
||||
}
|
||||
|
||||
/* get server time for time conversions and add
|
||||
code to use it and timezone since this is not UTC */
|
||||
|
||||
if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
|
||||
memcpy(server->cryptKey, rsp->EncryptionKey,
|
||||
CIFS_CRYPTO_KEY_SIZE);
|
||||
} else {
|
||||
rc = -EIO;
|
||||
goto neg_err_exit;
|
||||
}
|
||||
|
||||
cFYI(1,("LANMAN negotiated")); /* BB removeme BB */
|
||||
cFYI(1,("LANMAN negotiated"));
|
||||
/* we will not end up setting signing flags - as no signing
|
||||
was in LANMAN and server did not return the flags on */
|
||||
goto signing_check;
|
||||
#else /* weak security disabled */
|
||||
} else if(pSMBr->hdr.WordCount == 13) {
|
||||
cERROR(1,("mount failed, cifs module not built "
|
||||
"with CIFS_WEAK_PW_HASH support"));
|
||||
} else if(pSMBr->hdr.WordCount == 13) {
|
||||
cERROR(1,("mount failed, cifs module not built "
|
||||
"with CIFS_WEAK_PW_HASH support"));
|
||||
rc = -EOPNOTSUPP;
|
||||
#endif /* WEAK_PW_HASH */
|
||||
goto neg_err_exit;
|
||||
} else if(pSMBr->hdr.WordCount != 17) {
|
||||
/* unknown wct */
|
||||
rc = -EOPNOTSUPP;
|
||||
goto neg_err_exit;
|
||||
}
|
||||
goto neg_err_exit;
|
||||
} else if(pSMBr->hdr.WordCount != 17) {
|
||||
/* unknown wct */
|
||||
rc = -EOPNOTSUPP;
|
||||
goto neg_err_exit;
|
||||
}
|
||||
/* else wct == 17 NTLM */
|
||||
server->secMode = pSMBr->SecurityMode;
|
||||
if((server->secMode & SECMODE_USER) == 0)
|
||||
cFYI(1,("share mode security"));
|
||||
|
||||
server->secMode = pSMBr->SecurityMode;
|
||||
if((server->secMode & SECMODE_USER) == 0)
|
||||
cFYI(1,("share mode security"));
|
||||
|
||||
if((server->secMode & SECMODE_PW_ENCRYPT) == 0)
|
||||
if((server->secMode & SECMODE_PW_ENCRYPT) == 0)
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
if ((extended_security & CIFSSEC_MAY_PLNTXT) == 0)
|
||||
if ((extended_security & CIFSSEC_MAY_PLNTXT) == 0)
|
||||
#endif /* CIFS_WEAK_PW_HASH */
|
||||
cERROR(1,("Server requests plain text password"
|
||||
" but client support disabled"));
|
||||
cERROR(1,("Server requests plain text password"
|
||||
" but client support disabled"));
|
||||
|
||||
if(extended_security & CIFSSEC_MUST_NTLMV2)
|
||||
server->secType = NTLMv2;
|
||||
else
|
||||
server->secType = NTLM;
|
||||
/* else krb5 ... */
|
||||
if(extended_security & CIFSSEC_MUST_NTLMV2)
|
||||
server->secType = NTLMv2;
|
||||
else
|
||||
server->secType = NTLM;
|
||||
/* else krb5 ... */
|
||||
|
||||
/* one byte - no need to convert this or EncryptionKeyLen
|
||||
from little endian */
|
||||
server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
|
||||
/* probably no need to store and check maxvcs */
|
||||
server->maxBuf =
|
||||
min(le32_to_cpu(pSMBr->MaxBufferSize),
|
||||
/* one byte, so no need to convert this or EncryptionKeyLen from
|
||||
little endian */
|
||||
server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
|
||||
/* probably no need to store and check maxvcs */
|
||||
server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize),
|
||||
(__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
|
||||
server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
|
||||
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);
|
||||
/* BB with UTC do we ever need to be using srvr timezone? */
|
||||
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
|
||||
memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
|
||||
CIFS_CRYPTO_KEY_SIZE);
|
||||
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
|
||||
&& (pSMBr->EncryptionKeyLength == 0)) {
|
||||
/* decode security blob */
|
||||
} else
|
||||
server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
|
||||
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);
|
||||
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
|
||||
memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
|
||||
CIFS_CRYPTO_KEY_SIZE);
|
||||
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
|
||||
&& (pSMBr->EncryptionKeyLength == 0)) {
|
||||
/* decode security blob */
|
||||
} else if (server->secMode & SECMODE_PW_ENCRYPT) {
|
||||
rc = -EIO; /* no crypt key only if plain text pwd */
|
||||
goto neg_err_exit;
|
||||
}
|
||||
|
||||
/* BB might be helpful to save off the domain of server here */
|
||||
|
||||
if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
|
||||
(server->capabilities & CAP_EXTENDED_SECURITY)) {
|
||||
count = pSMBr->ByteCount;
|
||||
if (count < 16)
|
||||
rc = -EIO;
|
||||
|
||||
/* BB might be helpful to save off the domain of server here */
|
||||
|
||||
if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
|
||||
(server->capabilities & CAP_EXTENDED_SECURITY)) {
|
||||
count = pSMBr->ByteCount;
|
||||
if (count < 16)
|
||||
rc = -EIO;
|
||||
else if (count == 16) {
|
||||
server->secType = RawNTLMSSP;
|
||||
if (server->socketUseCount.counter > 1) {
|
||||
if (memcmp
|
||||
(server->server_GUID,
|
||||
pSMBr->u.extended_response.
|
||||
GUID, 16) != 0) {
|
||||
cFYI(1, ("server UID changed"));
|
||||
memcpy(server->
|
||||
server_GUID,
|
||||
pSMBr->u.
|
||||
extended_response.
|
||||
GUID, 16);
|
||||
}
|
||||
} else
|
||||
else if (count == 16) {
|
||||
server->secType = RawNTLMSSP;
|
||||
if (server->socketUseCount.counter > 1) {
|
||||
if (memcmp(server->server_GUID,
|
||||
pSMBr->u.extended_response.
|
||||
GUID, 16) != 0) {
|
||||
cFYI(1, ("server UID changed"));
|
||||
memcpy(server->server_GUID,
|
||||
pSMBr->u.extended_response.
|
||||
GUID, 16);
|
||||
} else {
|
||||
rc = decode_negTokenInit(pSMBr->u.
|
||||
extended_response.
|
||||
SecurityBlob,
|
||||
count - 16,
|
||||
&server->secType);
|
||||
if(rc == 1) {
|
||||
/* BB Need to fill struct for sessetup here */
|
||||
rc = -EOPNOTSUPP;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
pSMBr->u.extended_response.GUID,
|
||||
16);
|
||||
}
|
||||
} else
|
||||
memcpy(server->server_GUID,
|
||||
pSMBr->u.extended_response.GUID, 16);
|
||||
} else {
|
||||
rc = decode_negTokenInit(pSMBr->u.extended_response.
|
||||
SecurityBlob,
|
||||
count - 16,
|
||||
&server->secType);
|
||||
if(rc == 1) {
|
||||
/* BB Need to fill struct for sessetup here */
|
||||
rc = -EOPNOTSUPP;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
}
|
||||
} else
|
||||
server->capabilities &= ~CAP_EXTENDED_SECURITY;
|
||||
if(sign_CIFS_PDUs == FALSE) {
|
||||
if(server->secMode & SECMODE_SIGN_REQUIRED)
|
||||
cERROR(1,
|
||||
("Server requires /proc/fs/cifs/PacketSigningEnabled"));
|
||||
server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
||||
} else if(sign_CIFS_PDUs == 1) {
|
||||
if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
|
||||
server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
||||
}
|
||||
|
||||
} else
|
||||
server->capabilities &= ~CAP_EXTENDED_SECURITY;
|
||||
|
||||
signing_check:
|
||||
if(sign_CIFS_PDUs == FALSE) {
|
||||
if(server->secMode & SECMODE_SIGN_REQUIRED)
|
||||
cERROR(1,("Server requires "
|
||||
"/proc/fs/cifs/PacketSigningEnabled to be on"));
|
||||
server->secMode &=
|
||||
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
||||
} else if(sign_CIFS_PDUs == 1) {
|
||||
if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
|
||||
server->secMode &=
|
||||
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
||||
} else if(sign_CIFS_PDUs == 2) {
|
||||
if((server->secMode &
|
||||
(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
|
||||
cERROR(1,("signing required but server lacks support"));
|
||||
}
|
||||
}
|
||||
neg_err_exit:
|
||||
cifs_buf_release(pSMB);
|
||||
|
||||
cFYI(1,("negprot rc %d",rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -323,7 +323,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
|
|||
enum securityEnum type;
|
||||
__u16 action;
|
||||
int bytes_remaining;
|
||||
|
||||
|
||||
cFYI(1,("new sess setup"));
|
||||
if(ses == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче