]> err.no Git - linux-2.6/commitdiff
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
authorSteve French <sfrench@us.ibm.com>
Tue, 26 Aug 2008 16:56:05 +0000 (16:56 +0000)
committerSteve French <sfrench@us.ibm.com>
Tue, 26 Aug 2008 16:56:05 +0000 (16:56 +0000)
fs/Kconfig
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/asn1.c
fs/cifs/cifs_spnego.c
fs/cifs/cifs_spnego.h
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/sess.c

index d3873583360b84d69afa0632bbc070bb34584f3c..f0427105a619211fcf0f626f16e76d9263ad691a 100644 (file)
@@ -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
index f5d0083e09fa235bf30c0440f7132fb7e10a6dc7..526041a52d352c33427957b383fb3e18e99049b0 100644 (file)
@@ -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
 ------------
index 2bd6fe556f887b8e59f1668d8b7ebcd3db050edc..68b5c1169d9d7e3eff5a3aff67cfb60980fa2050 100644 (file)
@@ -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
+
+
index 5fabd2caf93c2b16b86e1e0f5b4c1f52c7bdfd23..1b09f167006160ad911211a83bd1a8a53f51db82 100644 (file)
@@ -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;
 
index 2434ab0e8791c4b51c2905731f30e761cf9e42af..117ef4bba68ec6c52f03164baaad5361e7937d69 100644 (file)
@@ -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;
 
index 05a34b17a1ab4411d87875525adfe772e6edf26d..e4041ec4d712943c412e0d97addbea7c4964c77a 100644 (file)
@@ -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.
index 7e1cf262effe7b5afb0640ce7822ebf4d0d5c15e..8dfd6f24d4884dbdaa024cbea8a7c4b63d2a2af7 100644 (file)
@@ -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 {
index 0711db65afe8025e0a4abafc56df66b7b2e3545f..4c13bcdb92a5f4800cbd9f1a1d8bb844e6844a5c 100644 (file)
@@ -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);
        }
index 848286861c314737961cc91f55f3e574930a17a7..9c548f110102ad89d8c507b1e325e2ab2f95d3a9 100644 (file)
@@ -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)
index ed150efbe27c93fbec1834767262453c47619e14..b537fad3bf50684c2b3405df74a69ea9dd9e29a3 100644 (file)
@@ -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)) {