mirror of
https://github.com/torvalds/linux.git
synced 2024-11-06 20:21:57 +00:00
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: [CIFS] check version in spnego upcall response [CIFS] Kerberos support not considered experimental anymore [CIFS] distinguish between Kerberos and MSKerberos in upcall cifs: add local server pointer to cifs_setup_session [CIFS] reindent misindented statement
This commit is contained in:
commit
b22dfb735a
@ -1984,7 +1984,6 @@ config CIFS_EXPERIMENTAL
|
||||
|
||||
config CIFS_UPCALL
|
||||
bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
|
||||
depends on CIFS_EXPERIMENTAL
|
||||
depends on KEYS
|
||||
help
|
||||
Enables an upcall mechanism for CIFS which accesses
|
||||
|
@ -4,7 +4,11 @@ Fix premature write failure on congested networks (we would give up
|
||||
on EAGAIN from the socket too quickly on large writes).
|
||||
Cifs_mkdir and cifs_create now respect the setgid bit on parent dir.
|
||||
Fix endian problems in acl (mode from/to cifs acl) on bigendian
|
||||
architectures.
|
||||
architectures. Fix problems with preserving timestamps on copying open
|
||||
files (e.g. "cp -a") to Windows servers. For mkdir and create honor setgid bit
|
||||
on parent directory when server supports Unix Extensions but not POSIX
|
||||
create. Update cifs.upcall version to handle new Kerberos sec flags
|
||||
(this requires update of cifs.upcall program from Samba).
|
||||
|
||||
Version 1.53
|
||||
------------
|
||||
|
@ -642,8 +642,30 @@ The statistics for the number of total SMBs and oplock breaks are different in
|
||||
that they represent all for that share, not just those for which the server
|
||||
returned success.
|
||||
|
||||
Also note that "cat /proc/fs/cifs/DebugData" will display information about
|
||||
Also note that "cat /proc/fs/cifs/DebugData" will display information about
|
||||
the active sessions and the shares that are mounted.
|
||||
Enabling Kerberos (extended security) works when CONFIG_CIFS_EXPERIMENTAL is
|
||||
on but requires a user space helper (from the Samba project). NTLM and NTLMv2 and
|
||||
LANMAN support do not require this helper.
|
||||
|
||||
Enabling Kerberos (extended security) works but requires version 1.2 or later
|
||||
of the helper program cifs.upcall to be present and to be configured in the
|
||||
/etc/request-key.conf file. The cifs.upcall helper program is from the Samba
|
||||
project(http://www.samba.org). NTLM and NTLMv2 and LANMAN support do not
|
||||
require this helper. Note that NTLMv2 security (which does not require the
|
||||
cifs.upcall helper program), instead of using Kerberos, is sufficient for
|
||||
some use cases.
|
||||
|
||||
Enabling DFS support (used to access shares transparently in an MS-DFS
|
||||
global name space) requires that CONFIG_CIFS_EXPERIMENTAL be enabled. In
|
||||
addition, DFS support for target shares which are specified as UNC
|
||||
names which begin with host names (rather than IP addresses) requires
|
||||
a user space helper (such as cifs.upcall) to be present in order to
|
||||
translate host names to ip address, and the user space helper must also
|
||||
be configured in the file /etc/request-key.conf
|
||||
|
||||
To use cifs Kerberos and DFS support, the Linux keyutils package should be
|
||||
installed and something like the following lines should be added to the
|
||||
/etc/request-key.conf file:
|
||||
|
||||
create cifs.spnego * * /usr/local/sbin/cifs.upcall %k
|
||||
create dns_resolver * * /usr/local/sbin/cifs.upcall %k
|
||||
|
||||
|
||||
|
@ -476,6 +476,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
||||
unsigned int cls, con, tag, oidlen, rc;
|
||||
bool use_ntlmssp = false;
|
||||
bool use_kerberos = false;
|
||||
bool use_mskerberos = false;
|
||||
|
||||
*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
|
||||
|
||||
@ -574,10 +575,12 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
||||
*(oid + 1), *(oid + 2), *(oid + 3)));
|
||||
|
||||
if (compare_oid(oid, oidlen, MSKRB5_OID,
|
||||
MSKRB5_OID_LEN))
|
||||
use_kerberos = true;
|
||||
MSKRB5_OID_LEN) &&
|
||||
!use_kerberos)
|
||||
use_mskerberos = true;
|
||||
else if (compare_oid(oid, oidlen, KRB5_OID,
|
||||
KRB5_OID_LEN))
|
||||
KRB5_OID_LEN) &&
|
||||
!use_mskerberos)
|
||||
use_kerberos = true;
|
||||
else if (compare_oid(oid, oidlen, NTLMSSP_OID,
|
||||
NTLMSSP_OID_LEN))
|
||||
@ -630,6 +633,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
||||
|
||||
if (use_kerberos)
|
||||
*secType = Kerberos;
|
||||
else if (use_mskerberos)
|
||||
*secType = MSKerberos;
|
||||
else if (use_ntlmssp)
|
||||
*secType = NTLMSSP;
|
||||
|
||||
|
@ -114,9 +114,11 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
|
||||
|
||||
dp = description + strlen(description);
|
||||
|
||||
/* for now, only sec=krb5 is valid */
|
||||
/* for now, only sec=krb5 and sec=mskrb5 are valid */
|
||||
if (server->secType == Kerberos)
|
||||
sprintf(dp, ";sec=krb5");
|
||||
else if (server->secType == MSKerberos)
|
||||
sprintf(dp, ";sec=mskrb5");
|
||||
else
|
||||
goto out;
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef _CIFS_SPNEGO_H
|
||||
#define _CIFS_SPNEGO_H
|
||||
|
||||
#define CIFS_SPNEGO_UPCALL_VERSION 1
|
||||
#define CIFS_SPNEGO_UPCALL_VERSION 2
|
||||
|
||||
/*
|
||||
* The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION.
|
||||
|
@ -80,7 +80,8 @@ enum securityEnum {
|
||||
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
|
||||
RawNTLMSSP, /* NTLMSSP without SPNEGO */
|
||||
NTLMSSP, /* NTLMSSP via SPNEGO */
|
||||
Kerberos /* Kerberos via SPNEGO */
|
||||
Kerberos, /* Kerberos via SPNEGO */
|
||||
MSKerberos, /* MS Kerberos via SPNEGO */
|
||||
};
|
||||
|
||||
enum protocolEnum {
|
||||
|
@ -3598,19 +3598,21 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
||||
char ntlm_session_key[CIFS_SESS_KEY_SIZE];
|
||||
bool ntlmv2_flag = false;
|
||||
int first_time = 0;
|
||||
struct TCP_Server_Info *server = pSesInfo->server;
|
||||
|
||||
/* what if server changes its buffer size after dropping the session? */
|
||||
if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
|
||||
if (server->maxBuf == 0) /* no need to send on reconnect */ {
|
||||
rc = CIFSSMBNegotiate(xid, pSesInfo);
|
||||
if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
|
||||
if (rc == -EAGAIN) {
|
||||
/* retry only once on 1st time connection */
|
||||
rc = CIFSSMBNegotiate(xid, pSesInfo);
|
||||
if (rc == -EAGAIN)
|
||||
rc = -EHOSTDOWN;
|
||||
}
|
||||
if (rc == 0) {
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
if (pSesInfo->server->tcpStatus != CifsExiting)
|
||||
pSesInfo->server->tcpStatus = CifsGood;
|
||||
if (server->tcpStatus != CifsExiting)
|
||||
server->tcpStatus = CifsGood;
|
||||
else
|
||||
rc = -EHOSTDOWN;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
@ -3623,23 +3625,22 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
||||
goto ss_err_exit;
|
||||
|
||||
pSesInfo->flags = 0;
|
||||
pSesInfo->capabilities = pSesInfo->server->capabilities;
|
||||
pSesInfo->capabilities = server->capabilities;
|
||||
if (linuxExtEnabled == 0)
|
||||
pSesInfo->capabilities &= (~CAP_UNIX);
|
||||
/* pSesInfo->sequence_number = 0;*/
|
||||
cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
|
||||
pSesInfo->server->secMode,
|
||||
pSesInfo->server->capabilities,
|
||||
pSesInfo->server->timeAdj));
|
||||
server->secMode, server->capabilities, server->timeAdj));
|
||||
|
||||
if (experimEnabled < 2)
|
||||
rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
|
||||
else if (extended_security
|
||||
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
|
||||
&& (pSesInfo->server->secType == NTLMSSP)) {
|
||||
&& (server->secType == NTLMSSP)) {
|
||||
rc = -EOPNOTSUPP;
|
||||
} else if (extended_security
|
||||
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
|
||||
&& (pSesInfo->server->secType == RawNTLMSSP)) {
|
||||
&& (server->secType == RawNTLMSSP)) {
|
||||
cFYI(1, ("NTLMSSP sesssetup"));
|
||||
rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
|
||||
nls_info);
|
||||
@ -3668,12 +3669,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
||||
|
||||
} else {
|
||||
SMBNTencrypt(pSesInfo->password,
|
||||
pSesInfo->server->cryptKey,
|
||||
server->cryptKey,
|
||||
ntlm_session_key);
|
||||
|
||||
if (first_time)
|
||||
cifs_calculate_mac_key(
|
||||
&pSesInfo->server->mac_signing_key,
|
||||
&server->mac_signing_key,
|
||||
ntlm_session_key,
|
||||
pSesInfo->password);
|
||||
}
|
||||
@ -3686,13 +3687,13 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
||||
nls_info);
|
||||
}
|
||||
} else { /* old style NTLM 0.12 session setup */
|
||||
SMBNTencrypt(pSesInfo->password, pSesInfo->server->cryptKey,
|
||||
SMBNTencrypt(pSesInfo->password, server->cryptKey,
|
||||
ntlm_session_key);
|
||||
|
||||
if (first_time)
|
||||
cifs_calculate_mac_key(
|
||||
&pSesInfo->server->mac_signing_key,
|
||||
ntlm_session_key, pSesInfo->password);
|
||||
cifs_calculate_mac_key(&server->mac_signing_key,
|
||||
ntlm_session_key,
|
||||
pSesInfo->password);
|
||||
|
||||
rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
|
||||
}
|
||||
|
@ -546,7 +546,8 @@ int cifs_get_inode_info(struct inode **pinode,
|
||||
if ((inode->i_mode & S_IWUGO) == 0 &&
|
||||
(attr & ATTR_READONLY) == 0)
|
||||
inode->i_mode |= (S_IWUGO & default_mode);
|
||||
inode->i_mode &= ~S_IFMT;
|
||||
|
||||
inode->i_mode &= ~S_IFMT;
|
||||
}
|
||||
/* clear write bits if ATTR_READONLY is set */
|
||||
if (attr & ATTR_READONLY)
|
||||
|
@ -505,7 +505,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
|
||||
unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
|
||||
} else
|
||||
ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
|
||||
} else if (type == Kerberos) {
|
||||
} else if (type == Kerberos || type == MSKerberos) {
|
||||
#ifdef CONFIG_CIFS_UPCALL
|
||||
struct cifs_spnego_msg *msg;
|
||||
spnego_key = cifs_get_spnego_key(ses);
|
||||
@ -516,6 +516,15 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
|
||||
}
|
||||
|
||||
msg = spnego_key->payload.data;
|
||||
/* check version field to make sure that cifs.upcall is
|
||||
sending us a response in an expected form */
|
||||
if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
|
||||
cERROR(1, ("incorrect version of cifs.upcall (expected"
|
||||
" %d but got %d)",
|
||||
CIFS_SPNEGO_UPCALL_VERSION, msg->version));
|
||||
rc = -EKEYREJECTED;
|
||||
goto ssetup_exit;
|
||||
}
|
||||
/* bail out if key is too long */
|
||||
if (msg->sesskey_len >
|
||||
sizeof(ses->server->mac_signing_key.data.krb5)) {
|
||||
|
Loading…
Reference in New Issue
Block a user