|
@@ -367,6 +367,185 @@ vt2_err:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+static int
|
|
|
+decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ u16 count;
|
|
|
+ char *guid = pSMBr->u.extended_response.GUID;
|
|
|
+ struct TCP_Server_Info *server = ses->server;
|
|
|
+
|
|
|
+ count = get_bcc(&pSMBr->hdr);
|
|
|
+ if (count < SMB1_CLIENT_GUID_SIZE)
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ spin_lock(&cifs_tcp_ses_lock);
|
|
|
+ if (server->srv_count > 1) {
|
|
|
+ spin_unlock(&cifs_tcp_ses_lock);
|
|
|
+ if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
|
|
|
+ cifs_dbg(FYI, "server UID changed\n");
|
|
|
+ memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ spin_unlock(&cifs_tcp_ses_lock);
|
|
|
+ memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (count == SMB1_CLIENT_GUID_SIZE) {
|
|
|
+ server->sec_ntlmssp = true;
|
|
|
+ } else {
|
|
|
+ count -= SMB1_CLIENT_GUID_SIZE;
|
|
|
+ rc = decode_negTokenInit(
|
|
|
+ pSMBr->u.extended_response.SecurityBlob, count, server);
|
|
|
+ if (rc != 1)
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
|
|
|
+{
|
|
|
+ bool srv_sign_required = server->sec_mode & server->vals->signing_required;
|
|
|
+ bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
|
|
|
+ bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Is signing required by mnt options? If not then check
|
|
|
+ * global_secflags to see if it is there.
|
|
|
+ */
|
|
|
+ if (!mnt_sign_required)
|
|
|
+ mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
|
|
|
+ CIFSSEC_MUST_SIGN);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If signing is required then it's automatically enabled too,
|
|
|
+ * otherwise, check to see if the secflags allow it.
|
|
|
+ */
|
|
|
+ mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
|
|
|
+ (global_secflags & CIFSSEC_MAY_SIGN);
|
|
|
+
|
|
|
+ /* If server requires signing, does client allow it? */
|
|
|
+ if (srv_sign_required) {
|
|
|
+ if (!mnt_sign_enabled) {
|
|
|
+ cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
|
|
|
+ return -ENOTSUPP;
|
|
|
+ }
|
|
|
+ server->sign = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If client requires signing, does server allow it? */
|
|
|
+ if (mnt_sign_required) {
|
|
|
+ if (!srv_sign_enabled) {
|
|
|
+ cifs_dbg(VFS, "Server does not support signing!");
|
|
|
+ return -ENOTSUPP;
|
|
|
+ }
|
|
|
+ server->sign = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
|
|
+static int
|
|
|
+decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
|
|
|
+{
|
|
|
+ __s16 tmp;
|
|
|
+ struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
|
|
|
+
|
|
|
+ if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ server->sec_mode = le16_to_cpu(rsp->SecurityMode);
|
|
|
+ server->maxReq = min_t(unsigned int,
|
|
|
+ le16_to_cpu(rsp->MaxMpxCount),
|
|
|
+ cifs_max_pending);
|
|
|
+ set_credits(server, server->maxReq);
|
|
|
+ server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
|
|
|
+ server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
|
|
|
+ /* 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->max_rw = 0xFF00;
|
|
|
+ server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
|
|
|
+ } else {
|
|
|
+ server->max_rw = 0;/* do not need to use raw anyway */
|
|
|
+ server->capabilities = CAP_MPX_MODE;
|
|
|
+ }
|
|
|
+ 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(rsp->SrvTime.Date,
|
|
|
+ rsp->SrvTime.Time, 0);
|
|
|
+ cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
|
|
|
+ (int)ts.tv_sec, (int)utc.tv_sec,
|
|
|
+ (int)(utc.tv_sec - ts.tv_sec));
|
|
|
+ val = (int)(utc.tv_sec - ts.tv_sec);
|
|
|
+ seconds = abs(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 */
|
|
|
+ }
|
|
|
+ cifs_dbg(FYI, "server->timeAdj: %d seconds\n", 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)) {
|
|
|
+ memcpy(server->cryptkey, rsp->EncryptionKey,
|
|
|
+ CIFS_CRYPTO_KEY_SIZE);
|
|
|
+ } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
|
|
|
+ return -EIO; /* need cryptkey unless plain text */
|
|
|
+ }
|
|
|
+
|
|
|
+ cifs_dbg(FYI, "LANMAN negotiated\n");
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline int
|
|
|
+decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
|
|
|
+{
|
|
|
+ cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+static bool
|
|
|
+should_set_ext_sec_flag(enum securityEnum sectype)
|
|
|
+{
|
|
|
+ switch (sectype) {
|
|
|
+ case RawNTLMSSP:
|
|
|
+ case Kerberos:
|
|
|
+ return true;
|
|
|
+ case Unspecified:
|
|
|
+ if (global_secflags &
|
|
|
+ (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
|
|
|
+ return true;
|
|
|
+ /* Fallthrough */
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
|
|
|
{
|
|
@@ -375,41 +554,24 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
|
|
|
int rc = 0;
|
|
|
int bytes_returned;
|
|
|
int i;
|
|
|
- struct TCP_Server_Info *server;
|
|
|
+ struct TCP_Server_Info *server = ses->server;
|
|
|
u16 count;
|
|
|
- unsigned int secFlags;
|
|
|
|
|
|
- if (ses->server)
|
|
|
- server = ses->server;
|
|
|
- else {
|
|
|
- rc = -EIO;
|
|
|
- return rc;
|
|
|
+ if (!server) {
|
|
|
+ WARN(1, "%s: server is NULL!\n", __func__);
|
|
|
+ return -EIO;
|
|
|
}
|
|
|
+
|
|
|
rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
|
|
|
(void **) &pSMB, (void **) &pSMBr);
|
|
|
if (rc)
|
|
|
return rc;
|
|
|
|
|
|
- /* if any of auth flags (ie not sign or seal) are overriden use them */
|
|
|
- if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
|
|
|
- secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
|
|
|
- else /* if override flags set only sign/seal OR them with global auth */
|
|
|
- secFlags = global_secflags | ses->overrideSecFlg;
|
|
|
-
|
|
|
- cifs_dbg(FYI, "secFlags 0x%x\n", secFlags);
|
|
|
-
|
|
|
pSMB->hdr.Mid = get_next_mid(server);
|
|
|
pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
|
|
|
|
|
|
- if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
|
|
|
- pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
|
|
|
- else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
|
|
|
- cifs_dbg(FYI, "Kerberos only mechanism, enable extended security\n");
|
|
|
- pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
|
|
|
- } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
|
|
|
- pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
|
|
|
- else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
|
|
|
- cifs_dbg(FYI, "NTLMSSP only mechanism, enable extended security\n");
|
|
|
+ if (should_set_ext_sec_flag(ses->sectype)) {
|
|
|
+ cifs_dbg(FYI, "Requesting extended security.");
|
|
|
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
|
|
|
}
|
|
|
|
|
@@ -436,127 +598,21 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
|
|
|
could not negotiate a common dialect */
|
|
|
rc = -EOPNOTSUPP;
|
|
|
goto neg_err_exit;
|
|
|
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
|
|
- } else if ((pSMBr->hdr.WordCount == 13)
|
|
|
- && ((server->dialect == LANMAN_PROT)
|
|
|
- || (server->dialect == LANMAN2_PROT))) {
|
|
|
- __s16 tmp;
|
|
|
- struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
|
|
|
-
|
|
|
- if ((secFlags & CIFSSEC_MAY_LANMAN) ||
|
|
|
- (secFlags & CIFSSEC_MAY_PLNTXT))
|
|
|
- server->secType = LANMAN;
|
|
|
- else {
|
|
|
- cifs_dbg(VFS, "mount failed weak security disabled in /proc/fs/cifs/SecurityFlags\n");
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
- goto neg_err_exit;
|
|
|
- }
|
|
|
- server->sec_mode = le16_to_cpu(rsp->SecurityMode);
|
|
|
- server->maxReq = min_t(unsigned int,
|
|
|
- le16_to_cpu(rsp->MaxMpxCount),
|
|
|
- cifs_max_pending);
|
|
|
- set_credits(server, server->maxReq);
|
|
|
- server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
|
|
|
- server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
|
|
|
- /* 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->max_rw = 0xFF00;
|
|
|
- server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
|
|
|
- } else {
|
|
|
- server->max_rw = 0;/* do not need to use raw anyway */
|
|
|
- server->capabilities = CAP_MPX_MODE;
|
|
|
- }
|
|
|
- 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(rsp->SrvTime.Date,
|
|
|
- rsp->SrvTime.Time, 0);
|
|
|
- cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
|
|
|
- (int)ts.tv_sec, (int)utc.tv_sec,
|
|
|
- (int)(utc.tv_sec - ts.tv_sec));
|
|
|
- val = (int)(utc.tv_sec - ts.tv_sec);
|
|
|
- seconds = abs(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 */
|
|
|
- }
|
|
|
- cifs_dbg(FYI, "server->timeAdj: %d seconds\n", 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)) {
|
|
|
- memcpy(ses->server->cryptkey, rsp->EncryptionKey,
|
|
|
- CIFS_CRYPTO_KEY_SIZE);
|
|
|
- } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
|
|
|
- rc = -EIO; /* need cryptkey unless plain text */
|
|
|
- goto neg_err_exit;
|
|
|
- }
|
|
|
-
|
|
|
- cifs_dbg(FYI, "LANMAN negotiated\n");
|
|
|
- /* 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) {
|
|
|
- cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
-#endif /* WEAK_PW_HASH */
|
|
|
- goto neg_err_exit;
|
|
|
+ server->negflavor = CIFS_NEGFLAVOR_LANMAN;
|
|
|
+ rc = decode_lanman_negprot_rsp(server, pSMBr);
|
|
|
+ goto signing_check;
|
|
|
} else if (pSMBr->hdr.WordCount != 17) {
|
|
|
/* unknown wct */
|
|
|
rc = -EOPNOTSUPP;
|
|
|
goto neg_err_exit;
|
|
|
}
|
|
|
- /* else wct == 17 NTLM */
|
|
|
+ /* else wct == 17, NTLM or better */
|
|
|
+
|
|
|
server->sec_mode = pSMBr->SecurityMode;
|
|
|
if ((server->sec_mode & SECMODE_USER) == 0)
|
|
|
cifs_dbg(FYI, "share mode security\n");
|
|
|
|
|
|
- if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
|
|
|
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
|
|
- if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
|
|
|
-#endif /* CIFS_WEAK_PW_HASH */
|
|
|
- cifs_dbg(VFS, "Server requests plain text password but client support disabled\n");
|
|
|
-
|
|
|
- if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
|
|
|
- server->secType = NTLMv2;
|
|
|
- else if (secFlags & CIFSSEC_MAY_NTLM)
|
|
|
- server->secType = NTLM;
|
|
|
- else if (secFlags & CIFSSEC_MAY_NTLMV2)
|
|
|
- server->secType = NTLMv2;
|
|
|
- else if (secFlags & CIFSSEC_MAY_KRB5)
|
|
|
- server->secType = Kerberos;
|
|
|
- else if (secFlags & CIFSSEC_MAY_NTLMSSP)
|
|
|
- server->secType = RawNTLMSSP;
|
|
|
- else if (secFlags & CIFSSEC_MAY_LANMAN)
|
|
|
- server->secType = LANMAN;
|
|
|
- else {
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
- cifs_dbg(VFS, "Invalid security type\n");
|
|
|
- goto neg_err_exit;
|
|
|
- }
|
|
|
- /* else ... any others ...? */
|
|
|
-
|
|
|
/* one byte, so no need to convert this or EncryptionKeyLen from
|
|
|
little endian */
|
|
|
server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
|
|
@@ -569,90 +625,26 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
|
|
|
server->capabilities = le32_to_cpu(pSMBr->Capabilities);
|
|
|
server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
|
|
|
server->timeAdj *= 60;
|
|
|
+
|
|
|
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
|
|
|
+ server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
|
|
|
memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
|
|
|
CIFS_CRYPTO_KEY_SIZE);
|
|
|
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
|
|
|
server->capabilities & CAP_EXTENDED_SECURITY) &&
|
|
|
(pSMBr->EncryptionKeyLength == 0)) {
|
|
|
- /* decode security blob */
|
|
|
- count = get_bcc(&pSMBr->hdr);
|
|
|
- if (count < 16) {
|
|
|
- rc = -EIO;
|
|
|
- goto neg_err_exit;
|
|
|
- }
|
|
|
- spin_lock(&cifs_tcp_ses_lock);
|
|
|
- if (server->srv_count > 1) {
|
|
|
- spin_unlock(&cifs_tcp_ses_lock);
|
|
|
- if (memcmp(server->server_GUID,
|
|
|
- pSMBr->u.extended_response.
|
|
|
- GUID, 16) != 0) {
|
|
|
- cifs_dbg(FYI, "server UID changed\n");
|
|
|
- memcpy(server->server_GUID,
|
|
|
- pSMBr->u.extended_response.GUID,
|
|
|
- 16);
|
|
|
- }
|
|
|
- } else {
|
|
|
- spin_unlock(&cifs_tcp_ses_lock);
|
|
|
- memcpy(server->server_GUID,
|
|
|
- pSMBr->u.extended_response.GUID, 16);
|
|
|
- }
|
|
|
-
|
|
|
- if (count == 16) {
|
|
|
- server->secType = RawNTLMSSP;
|
|
|
- } else {
|
|
|
- rc = decode_negTokenInit(pSMBr->u.extended_response.
|
|
|
- SecurityBlob, count - 16,
|
|
|
- server);
|
|
|
- if (rc == 1)
|
|
|
- rc = 0;
|
|
|
- else
|
|
|
- rc = -EINVAL;
|
|
|
- if (server->secType == Kerberos) {
|
|
|
- if (!server->sec_kerberos &&
|
|
|
- !server->sec_mskerberos)
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
- } else if (server->secType == RawNTLMSSP) {
|
|
|
- if (!server->sec_ntlmssp)
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
- } else
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
- }
|
|
|
+ server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
|
|
|
+ rc = decode_ext_sec_blob(ses, pSMBr);
|
|
|
} else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
|
|
|
rc = -EIO; /* no crypt key only if plain text pwd */
|
|
|
- goto neg_err_exit;
|
|
|
- } else
|
|
|
- server->capabilities &= ~CAP_EXTENDED_SECURITY;
|
|
|
-
|
|
|
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
|
|
-signing_check:
|
|
|
-#endif
|
|
|
- if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
|
|
|
- /* MUST_SIGN already includes the MAY_SIGN FLAG
|
|
|
- so if this is zero it means that signing is disabled */
|
|
|
- cifs_dbg(FYI, "Signing disabled\n");
|
|
|
- if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
|
|
|
- cifs_dbg(VFS, "Server requires packet signing to be enabled in /proc/fs/cifs/SecurityFlags\n");
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
- }
|
|
|
- server->sec_mode &=
|
|
|
- ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
|
|
- } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
|
|
|
- /* signing required */
|
|
|
- cifs_dbg(FYI, "Must sign - secFlags 0x%x\n", secFlags);
|
|
|
- if ((server->sec_mode &
|
|
|
- (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
|
|
|
- cifs_dbg(VFS, "signing required but server lacks support\n");
|
|
|
- rc = -EOPNOTSUPP;
|
|
|
- } else
|
|
|
- server->sec_mode |= SECMODE_SIGN_REQUIRED;
|
|
|
} else {
|
|
|
- /* signing optional ie CIFSSEC_MAY_SIGN */
|
|
|
- if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
|
|
|
- server->sec_mode &=
|
|
|
- ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
|
|
+ server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
|
|
|
+ server->capabilities &= ~CAP_EXTENDED_SECURITY;
|
|
|
}
|
|
|
|
|
|
+signing_check:
|
|
|
+ if (!rc)
|
|
|
+ rc = cifs_enable_signing(server, ses->sign);
|
|
|
neg_err_exit:
|
|
|
cifs_buf_release(pSMB);
|
|
|
|
|
@@ -777,9 +769,8 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
|
|
|
|
|
|
pSMB->hdr.Mid = get_next_mid(ses->server);
|
|
|
|
|
|
- if (ses->server->sec_mode &
|
|
|
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
|
|
- pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
|
|
+ if (ses->server->sign)
|
|
|
+ pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
|
|
|
|
|
pSMB->hdr.Uid = ses->Suid;
|
|
|
|
|
@@ -1540,8 +1531,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
|
|
|
switch (mid->mid_state) {
|
|
|
case MID_RESPONSE_RECEIVED:
|
|
|
/* result already set, check signature */
|
|
|
- if (server->sec_mode &
|
|
|
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
|
|
|
+ if (server->sign) {
|
|
|
int rc = 0;
|
|
|
|
|
|
rc = cifs_verify_signature(&rqst, server,
|
|
@@ -3940,6 +3930,7 @@ QFileInfoRetry:
|
|
|
pSMB->Pad = 0;
|
|
|
pSMB->Fid = netfid;
|
|
|
inc_rfc1001_len(pSMB, byte_count);
|
|
|
+ pSMB->t2.ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -4108,6 +4099,7 @@ UnixQFileInfoRetry:
|
|
|
pSMB->Pad = 0;
|
|
|
pSMB->Fid = netfid;
|
|
|
inc_rfc1001_len(pSMB, byte_count);
|
|
|
+ pSMB->t2.ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -4794,11 +4786,8 @@ getDFSRetry:
|
|
|
strncpy(pSMB->RequestFileName, search_name, name_len);
|
|
|
}
|
|
|
|
|
|
- if (ses->server) {
|
|
|
- if (ses->server->sec_mode &
|
|
|
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
|
|
- pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
|
|
- }
|
|
|
+ if (ses->server && ses->server->sign)
|
|
|
+ pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
|
|
|
|
|
pSMB->hdr.Uid = ses->Suid;
|
|
|
|