]> err.no Git - linux-2.6/blobdiff - fs/cifs/cifssmb.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6] / fs / cifs / cifssmb.c
index a6ff324bc135dd9ad1aeb7fc38c3ac2eb3141ef0..f0d9a485d0951f29c3f140ebda33391d7471a53d 100644 (file)
 #include <asm/uaccess.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
+#include "cifsacl.h"
 #include "cifsproto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
-#include "cifsacl.h"
 
 #ifdef CONFIG_CIFS_POSIX
 static struct {
@@ -438,8 +438,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 
        pSMB->hdr.Mid = GetNextMid(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) {
+               cFYI(1, ("Kerberos only mechanism, enable extended security"));
+               pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+       }
 
        count = 0;
        for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -573,7 +578,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                server->secType = NTLM;
        else if (secFlags & CIFSSEC_MAY_NTLMV2)
                server->secType = NTLMv2;
-       /* else krb5 ... any others ... */
+       else if (secFlags & CIFSSEC_MAY_KRB5)
+               server->secType = Kerberos;
+       else if (secFlags & CIFSSEC_MAY_LANMAN)
+               server->secType = LANMAN;
+/* #ifdef CONFIG_CIFS_EXPERIMENTAL
+       else if (secFlags & CIFSSEC_MAY_PLNTXT)
+               server->secType = ??
+#endif */
+       else {
+               rc = -EOPNOTSUPP;
+               cERROR(1, ("Invalid security type"));
+               goto neg_err_exit;
+       }
+       /* else ... any others ...? */
 
        /* one byte, so no need to convert this or EncryptionKeyLen from
           little endian */
@@ -603,22 +621,26 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
                (server->capabilities & CAP_EXTENDED_SECURITY)) {
                count = pSMBr->ByteCount;
-               if (count < 16)
+               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
+                       goto neg_err_exit;
+               }
+
+               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);
+                                       pSMBr->u.extended_response.GUID,
+                                       16);
+                       }
+               } else
+                       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,
@@ -641,10 +663,12 @@ signing_check:
                /* MUST_SIGN already includes the MAY_SIGN FLAG
                   so if this is zero it means that signing is disabled */
                cFYI(1, ("Signing disabled"));
-               if (server->secMode & SECMODE_SIGN_REQUIRED)
+               if (server->secMode & SECMODE_SIGN_REQUIRED) {
                        cERROR(1, ("Server requires "
-                                  "/proc/fs/cifs/PacketSigningEnabled "
-                                  "to be on"));
+                                  "packet signing to be enabled in "
+                                  "/proc/fs/cifs/SecurityFlags."));
+                       rc = -EOPNOTSUPP;
+               }
                server->secMode &=
                        ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
        } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
@@ -1051,7 +1075,7 @@ PsxCreat:
                                InformationLevel) - 4;
        offset = param_offset + params;
        pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
-       pdata->Level = SMB_QUERY_FILE_UNIX_BASIC;
+       pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
        pdata->Permissions = cpu_to_le64(mode);
        pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
        pdata->OpenFlags =  cpu_to_le32(*pOplock);
@@ -1097,8 +1121,8 @@ PsxCreat:
        if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
                *pOplock |= CIFS_CREATE_ACTION;
        /* check to make sure response data is there */
-       if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) {
-               pRetData->Type = -1; /* unknown */
+       if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
+               pRetData->Type = cpu_to_le32(-1); /* unknown */
 #ifdef CONFIG_CIFS_DEBUG2
                cFYI(1, ("unknown type"));
 #endif
@@ -1106,7 +1130,7 @@ PsxCreat:
                if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
                                        + sizeof(FILE_UNIX_BASIC_INFO)) {
                        cERROR(1, ("Open response data too small"));
-                       pRetData->Type = -1;
+                       pRetData->Type = cpu_to_le32(-1);
                        goto psx_create_err;
                }
                memcpy((char *) pRetData,
@@ -1422,9 +1446,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
 
        iov[0].iov_base = (char *)pSMB;
        iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
-       rc = SendReceive2(xid, tcon->ses, iov,
-                         1 /* num iovecs */,
-                         &resp_buf_type, 0);
+       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
+                        &resp_buf_type, 0 /* not long op */, 1 /* log err */ );
        cifs_stats_inc(&tcon->num_reads);
        pSMBr = (READ_RSP *)iov[0].iov_base;
        if (rc) {
@@ -1643,7 +1666,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 
 
        rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
-                         long_op);
+                         long_op, 0 /* do not log STATUS code */ );
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
                cFYI(1, ("Send error Write2 = %d", rc));
@@ -3040,6 +3063,7 @@ GetExtAttrOut:
 
 #endif /* CONFIG_POSIX */
 
+#ifdef CONFIG_CIFS_EXPERIMENTAL
 /* Get Security Descriptor (by handle) from remote server for a file or dir */
 int
 CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3069,7 +3093,8 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
        iov[0].iov_base = (char *)pSMB;
        iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
 
-       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
+       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
+                        0 /* not long op */, 0 /* do not log STATUS codes */ );
        cifs_stats_inc(&tcon->num_acl_get);
        if (rc) {
                cFYI(1, ("Send error in QuerySecDesc = %d", rc));
@@ -3089,8 +3114,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                        goto qsec_out;
                pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
 
-               cERROR(1, ("smb %p parm %p data %p",
-                         pSMBr, parm, psec_desc));  /* BB removeme BB */
+               cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc));
 
                if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
                        rc = -EIO;      /* bad smb */
@@ -3099,7 +3123,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 
 /* BB check that data area is minimum length and as big as acl_len */
 
-               acl_len = le32_to_cpu(*(__le32 *)parm);
+               acl_len = le32_to_cpu(*parm);
                /* BB check if (acl_len > bufsize) */
 
                parse_sec_desc(psec_desc, acl_len);
@@ -3112,6 +3136,7 @@ qsec_out:
 /*     cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
        return rc;
 }
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
 
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */