diff options
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 158 |
1 files changed, 82 insertions, 76 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 8eb102f940d4..f0d9a485d095 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | #include "cifspdu.h" | 35 | #include "cifspdu.h" |
36 | #include "cifsglob.h" | 36 | #include "cifsglob.h" |
37 | #include "cifsacl.h" | ||
37 | #include "cifsproto.h" | 38 | #include "cifsproto.h" |
38 | #include "cifs_unicode.h" | 39 | #include "cifs_unicode.h" |
39 | #include "cifs_debug.h" | 40 | #include "cifs_debug.h" |
40 | #include "cifsacl.h" | ||
41 | 41 | ||
42 | #ifdef CONFIG_CIFS_POSIX | 42 | #ifdef CONFIG_CIFS_POSIX |
43 | static struct { | 43 | static struct { |
@@ -94,9 +94,8 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) | |||
94 | write_lock(&GlobalSMBSeslock); | 94 | write_lock(&GlobalSMBSeslock); |
95 | list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { | 95 | list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { |
96 | open_file = list_entry(tmp, struct cifsFileInfo, tlist); | 96 | open_file = list_entry(tmp, struct cifsFileInfo, tlist); |
97 | if (open_file) { | 97 | if (open_file) |
98 | open_file->invalidHandle = TRUE; | 98 | open_file->invalidHandle = TRUE; |
99 | } | ||
100 | } | 99 | } |
101 | write_unlock(&GlobalSMBSeslock); | 100 | write_unlock(&GlobalSMBSeslock); |
102 | /* BB Add call to invalidate_inodes(sb) for all superblocks mounted | 101 | /* BB Add call to invalidate_inodes(sb) for all superblocks mounted |
@@ -439,8 +438,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
439 | 438 | ||
440 | pSMB->hdr.Mid = GetNextMid(server); | 439 | pSMB->hdr.Mid = GetNextMid(server); |
441 | pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); | 440 | pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); |
441 | |||
442 | if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) | 442 | if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) |
443 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; | 443 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; |
444 | else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) { | ||
445 | cFYI(1, ("Kerberos only mechanism, enable extended security")); | ||
446 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; | ||
447 | } | ||
444 | 448 | ||
445 | count = 0; | 449 | count = 0; |
446 | for (i = 0; i < CIFS_NUM_PROT; i++) { | 450 | for (i = 0; i < CIFS_NUM_PROT; i++) { |
@@ -513,7 +517,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
513 | (int)ts.tv_sec, (int)utc.tv_sec, | 517 | (int)ts.tv_sec, (int)utc.tv_sec, |
514 | (int)(utc.tv_sec - ts.tv_sec))); | 518 | (int)(utc.tv_sec - ts.tv_sec))); |
515 | val = (int)(utc.tv_sec - ts.tv_sec); | 519 | val = (int)(utc.tv_sec - ts.tv_sec); |
516 | seconds = val < 0 ? -val : val; | 520 | seconds = abs(val); |
517 | result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; | 521 | result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; |
518 | remain = seconds % MIN_TZ_ADJ; | 522 | remain = seconds % MIN_TZ_ADJ; |
519 | if (remain >= (MIN_TZ_ADJ / 2)) | 523 | if (remain >= (MIN_TZ_ADJ / 2)) |
@@ -574,7 +578,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
574 | server->secType = NTLM; | 578 | server->secType = NTLM; |
575 | else if (secFlags & CIFSSEC_MAY_NTLMV2) | 579 | else if (secFlags & CIFSSEC_MAY_NTLMV2) |
576 | server->secType = NTLMv2; | 580 | server->secType = NTLMv2; |
577 | /* else krb5 ... any others ... */ | 581 | else if (secFlags & CIFSSEC_MAY_KRB5) |
582 | server->secType = Kerberos; | ||
583 | else if (secFlags & CIFSSEC_MAY_LANMAN) | ||
584 | server->secType = LANMAN; | ||
585 | /* #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
586 | else if (secFlags & CIFSSEC_MAY_PLNTXT) | ||
587 | server->secType = ?? | ||
588 | #endif */ | ||
589 | else { | ||
590 | rc = -EOPNOTSUPP; | ||
591 | cERROR(1, ("Invalid security type")); | ||
592 | goto neg_err_exit; | ||
593 | } | ||
594 | /* else ... any others ...? */ | ||
578 | 595 | ||
579 | /* one byte, so no need to convert this or EncryptionKeyLen from | 596 | /* one byte, so no need to convert this or EncryptionKeyLen from |
580 | little endian */ | 597 | little endian */ |
@@ -604,22 +621,26 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
604 | if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && | 621 | if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && |
605 | (server->capabilities & CAP_EXTENDED_SECURITY)) { | 622 | (server->capabilities & CAP_EXTENDED_SECURITY)) { |
606 | count = pSMBr->ByteCount; | 623 | count = pSMBr->ByteCount; |
607 | if (count < 16) | 624 | if (count < 16) { |
608 | rc = -EIO; | 625 | rc = -EIO; |
609 | else if (count == 16) { | 626 | goto neg_err_exit; |
610 | server->secType = RawNTLMSSP; | 627 | } |
611 | if (server->socketUseCount.counter > 1) { | 628 | |
612 | if (memcmp(server->server_GUID, | 629 | if (server->socketUseCount.counter > 1) { |
613 | pSMBr->u.extended_response. | 630 | if (memcmp(server->server_GUID, |
614 | GUID, 16) != 0) { | 631 | pSMBr->u.extended_response. |
615 | cFYI(1, ("server UID changed")); | 632 | GUID, 16) != 0) { |
616 | memcpy(server->server_GUID, | 633 | cFYI(1, ("server UID changed")); |
617 | pSMBr->u.extended_response.GUID, | ||
618 | 16); | ||
619 | } | ||
620 | } else | ||
621 | memcpy(server->server_GUID, | 634 | memcpy(server->server_GUID, |
622 | pSMBr->u.extended_response.GUID, 16); | 635 | pSMBr->u.extended_response.GUID, |
636 | 16); | ||
637 | } | ||
638 | } else | ||
639 | memcpy(server->server_GUID, | ||
640 | pSMBr->u.extended_response.GUID, 16); | ||
641 | |||
642 | if (count == 16) { | ||
643 | server->secType = RawNTLMSSP; | ||
623 | } else { | 644 | } else { |
624 | rc = decode_negTokenInit(pSMBr->u.extended_response. | 645 | rc = decode_negTokenInit(pSMBr->u.extended_response. |
625 | SecurityBlob, | 646 | SecurityBlob, |
@@ -642,10 +663,12 @@ signing_check: | |||
642 | /* MUST_SIGN already includes the MAY_SIGN FLAG | 663 | /* MUST_SIGN already includes the MAY_SIGN FLAG |
643 | so if this is zero it means that signing is disabled */ | 664 | so if this is zero it means that signing is disabled */ |
644 | cFYI(1, ("Signing disabled")); | 665 | cFYI(1, ("Signing disabled")); |
645 | if (server->secMode & SECMODE_SIGN_REQUIRED) | 666 | if (server->secMode & SECMODE_SIGN_REQUIRED) { |
646 | cERROR(1, ("Server requires " | 667 | cERROR(1, ("Server requires " |
647 | "/proc/fs/cifs/PacketSigningEnabled " | 668 | "packet signing to be enabled in " |
648 | "to be on")); | 669 | "/proc/fs/cifs/SecurityFlags.")); |
670 | rc = -EOPNOTSUPP; | ||
671 | } | ||
649 | server->secMode &= | 672 | server->secMode &= |
650 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | 673 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); |
651 | } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { | 674 | } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { |
@@ -1052,7 +1075,7 @@ PsxCreat: | |||
1052 | InformationLevel) - 4; | 1075 | InformationLevel) - 4; |
1053 | offset = param_offset + params; | 1076 | offset = param_offset + params; |
1054 | pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); | 1077 | pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); |
1055 | pdata->Level = SMB_QUERY_FILE_UNIX_BASIC; | 1078 | pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); |
1056 | pdata->Permissions = cpu_to_le64(mode); | 1079 | pdata->Permissions = cpu_to_le64(mode); |
1057 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); | 1080 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); |
1058 | pdata->OpenFlags = cpu_to_le32(*pOplock); | 1081 | pdata->OpenFlags = cpu_to_le32(*pOplock); |
@@ -1098,8 +1121,8 @@ PsxCreat: | |||
1098 | if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) | 1121 | if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) |
1099 | *pOplock |= CIFS_CREATE_ACTION; | 1122 | *pOplock |= CIFS_CREATE_ACTION; |
1100 | /* check to make sure response data is there */ | 1123 | /* check to make sure response data is there */ |
1101 | if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) { | 1124 | if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { |
1102 | pRetData->Type = -1; /* unknown */ | 1125 | pRetData->Type = cpu_to_le32(-1); /* unknown */ |
1103 | #ifdef CONFIG_CIFS_DEBUG2 | 1126 | #ifdef CONFIG_CIFS_DEBUG2 |
1104 | cFYI(1, ("unknown type")); | 1127 | cFYI(1, ("unknown type")); |
1105 | #endif | 1128 | #endif |
@@ -1107,12 +1130,12 @@ PsxCreat: | |||
1107 | if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) | 1130 | if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) |
1108 | + sizeof(FILE_UNIX_BASIC_INFO)) { | 1131 | + sizeof(FILE_UNIX_BASIC_INFO)) { |
1109 | cERROR(1, ("Open response data too small")); | 1132 | cERROR(1, ("Open response data too small")); |
1110 | pRetData->Type = -1; | 1133 | pRetData->Type = cpu_to_le32(-1); |
1111 | goto psx_create_err; | 1134 | goto psx_create_err; |
1112 | } | 1135 | } |
1113 | memcpy((char *) pRetData, | 1136 | memcpy((char *) pRetData, |
1114 | (char *)psx_rsp + sizeof(OPEN_PSX_RSP), | 1137 | (char *)psx_rsp + sizeof(OPEN_PSX_RSP), |
1115 | sizeof (FILE_UNIX_BASIC_INFO)); | 1138 | sizeof(FILE_UNIX_BASIC_INFO)); |
1116 | } | 1139 | } |
1117 | 1140 | ||
1118 | psx_create_err: | 1141 | psx_create_err: |
@@ -1193,9 +1216,9 @@ OldOpenRetry: | |||
1193 | } | 1216 | } |
1194 | if (*pOplock & REQ_OPLOCK) | 1217 | if (*pOplock & REQ_OPLOCK) |
1195 | pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); | 1218 | pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); |
1196 | else if (*pOplock & REQ_BATCHOPLOCK) { | 1219 | else if (*pOplock & REQ_BATCHOPLOCK) |
1197 | pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); | 1220 | pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); |
1198 | } | 1221 | |
1199 | pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); | 1222 | pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); |
1200 | /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ | 1223 | /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ |
1201 | /* 0 = read | 1224 | /* 0 = read |
@@ -1310,9 +1333,8 @@ openRetry: | |||
1310 | } | 1333 | } |
1311 | if (*pOplock & REQ_OPLOCK) | 1334 | if (*pOplock & REQ_OPLOCK) |
1312 | pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK); | 1335 | pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK); |
1313 | else if (*pOplock & REQ_BATCHOPLOCK) { | 1336 | else if (*pOplock & REQ_BATCHOPLOCK) |
1314 | pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); | 1337 | pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); |
1315 | } | ||
1316 | pSMB->DesiredAccess = cpu_to_le32(access_flags); | 1338 | pSMB->DesiredAccess = cpu_to_le32(access_flags); |
1317 | pSMB->AllocationSize = 0; | 1339 | pSMB->AllocationSize = 0; |
1318 | /* set file as system file if special file such | 1340 | /* set file as system file if special file such |
@@ -1424,9 +1446,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, | |||
1424 | 1446 | ||
1425 | iov[0].iov_base = (char *)pSMB; | 1447 | iov[0].iov_base = (char *)pSMB; |
1426 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; | 1448 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; |
1427 | rc = SendReceive2(xid, tcon->ses, iov, | 1449 | rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, |
1428 | 1 /* num iovecs */, | 1450 | &resp_buf_type, 0 /* not long op */, 1 /* log err */ ); |
1429 | &resp_buf_type, 0); | ||
1430 | cifs_stats_inc(&tcon->num_reads); | 1451 | cifs_stats_inc(&tcon->num_reads); |
1431 | pSMBr = (READ_RSP *)iov[0].iov_base; | 1452 | pSMBr = (READ_RSP *)iov[0].iov_base; |
1432 | if (rc) { | 1453 | if (rc) { |
@@ -1446,11 +1467,11 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, | |||
1446 | *nbytes = 0; | 1467 | *nbytes = 0; |
1447 | } else { | 1468 | } else { |
1448 | pReadData = (char *) (&pSMBr->hdr.Protocol) + | 1469 | pReadData = (char *) (&pSMBr->hdr.Protocol) + |
1449 | le16_to_cpu(pSMBr->DataOffset); | 1470 | le16_to_cpu(pSMBr->DataOffset); |
1450 | /* if (rc = copy_to_user(buf, pReadData, data_length)) { | 1471 | /* if (rc = copy_to_user(buf, pReadData, data_length)) { |
1451 | cERROR(1,("Faulting on read rc = %d",rc)); | 1472 | cERROR(1,("Faulting on read rc = %d",rc)); |
1452 | rc = -EFAULT; | 1473 | rc = -EFAULT; |
1453 | }*/ /* can not use copy_to_user when using page cache*/ | 1474 | }*/ /* can not use copy_to_user when using page cache*/ |
1454 | if (*buf) | 1475 | if (*buf) |
1455 | memcpy(*buf, pReadData, data_length); | 1476 | memcpy(*buf, pReadData, data_length); |
1456 | } | 1477 | } |
@@ -1645,7 +1666,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
1645 | 1666 | ||
1646 | 1667 | ||
1647 | rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, | 1668 | rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, |
1648 | long_op); | 1669 | long_op, 0 /* do not log STATUS code */ ); |
1649 | cifs_stats_inc(&tcon->num_writes); | 1670 | cifs_stats_inc(&tcon->num_writes); |
1650 | if (rc) { | 1671 | if (rc) { |
1651 | cFYI(1, ("Send error Write2 = %d", rc)); | 1672 | cFYI(1, ("Send error Write2 = %d", rc)); |
@@ -2538,7 +2559,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, | |||
2538 | cFYI(1, ("data starts after end of smb")); | 2559 | cFYI(1, ("data starts after end of smb")); |
2539 | return -EINVAL; | 2560 | return -EINVAL; |
2540 | } else if (data_count + *ppdata > end_of_smb) { | 2561 | } else if (data_count + *ppdata > end_of_smb) { |
2541 | cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p", | 2562 | cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p", |
2542 | *ppdata, data_count, (data_count + *ppdata), | 2563 | *ppdata, data_count, (data_count + *ppdata), |
2543 | end_of_smb, pSMBr)); | 2564 | end_of_smb, pSMBr)); |
2544 | return -EINVAL; | 2565 | return -EINVAL; |
@@ -2615,7 +2636,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | |||
2615 | reparse_buf->TargetNameOffset + | 2636 | reparse_buf->TargetNameOffset + |
2616 | reparse_buf->TargetNameLen) > | 2637 | reparse_buf->TargetNameLen) > |
2617 | end_of_smb) { | 2638 | end_of_smb) { |
2618 | cFYI(1,("reparse buf goes beyond SMB")); | 2639 | cFYI(1, ("reparse buf beyond SMB")); |
2619 | rc = -EIO; | 2640 | rc = -EIO; |
2620 | goto qreparse_out; | 2641 | goto qreparse_out; |
2621 | } | 2642 | } |
@@ -3042,25 +3063,12 @@ GetExtAttrOut: | |||
3042 | 3063 | ||
3043 | #endif /* CONFIG_POSIX */ | 3064 | #endif /* CONFIG_POSIX */ |
3044 | 3065 | ||
3045 | 3066 | #ifdef CONFIG_CIFS_EXPERIMENTAL | |
3046 | /* security id for everyone */ | ||
3047 | static const struct cifs_sid sid_everyone = | ||
3048 | {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; | ||
3049 | /* group users */ | ||
3050 | static const struct cifs_sid sid_user = | ||
3051 | {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | ||
3052 | |||
3053 | /* Convert CIFS ACL to POSIX form */ | ||
3054 | static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len) | ||
3055 | { | ||
3056 | return 0; | ||
3057 | } | ||
3058 | |||
3059 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | 3067 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ |
3060 | int | 3068 | int |
3061 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | 3069 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, |
3062 | /* BB fix up return info */ char *acl_inf, const int buflen, | 3070 | /* BB fix up return info */ char *acl_inf, const int buflen, |
3063 | const int acl_type /* ACCESS/DEFAULT not sure implication */) | 3071 | const int acl_type) |
3064 | { | 3072 | { |
3065 | int rc = 0; | 3073 | int rc = 0; |
3066 | int buf_type = 0; | 3074 | int buf_type = 0; |
@@ -3085,12 +3093,13 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3085 | iov[0].iov_base = (char *)pSMB; | 3093 | iov[0].iov_base = (char *)pSMB; |
3086 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; | 3094 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; |
3087 | 3095 | ||
3088 | rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0); | 3096 | rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, |
3097 | 0 /* not long op */, 0 /* do not log STATUS codes */ ); | ||
3089 | cifs_stats_inc(&tcon->num_acl_get); | 3098 | cifs_stats_inc(&tcon->num_acl_get); |
3090 | if (rc) { | 3099 | if (rc) { |
3091 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | 3100 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); |
3092 | } else { /* decode response */ | 3101 | } else { /* decode response */ |
3093 | struct cifs_sid *psec_desc; | 3102 | struct cifs_ntsd *psec_desc; |
3094 | __le32 * parm; | 3103 | __le32 * parm; |
3095 | int parm_len; | 3104 | int parm_len; |
3096 | int data_len; | 3105 | int data_len; |
@@ -3105,8 +3114,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3105 | goto qsec_out; | 3114 | goto qsec_out; |
3106 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; | 3115 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; |
3107 | 3116 | ||
3108 | cERROR(1, ("smb %p parm %p data %p", | 3117 | cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc)); |
3109 | pSMBr, parm, psec_desc)); /* BB removeme BB */ | ||
3110 | 3118 | ||
3111 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { | 3119 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { |
3112 | rc = -EIO; /* bad smb */ | 3120 | rc = -EIO; /* bad smb */ |
@@ -3115,7 +3123,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3115 | 3123 | ||
3116 | /* BB check that data area is minimum length and as big as acl_len */ | 3124 | /* BB check that data area is minimum length and as big as acl_len */ |
3117 | 3125 | ||
3118 | acl_len = le32_to_cpu(*(__le32 *)parm); | 3126 | acl_len = le32_to_cpu(*parm); |
3119 | /* BB check if (acl_len > bufsize) */ | 3127 | /* BB check if (acl_len > bufsize) */ |
3120 | 3128 | ||
3121 | parse_sec_desc(psec_desc, acl_len); | 3129 | parse_sec_desc(psec_desc, acl_len); |
@@ -3128,6 +3136,7 @@ qsec_out: | |||
3128 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ | 3136 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ |
3129 | return rc; | 3137 | return rc; |
3130 | } | 3138 | } |
3139 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
3131 | 3140 | ||
3132 | /* Legacy Query Path Information call for lookup to old servers such | 3141 | /* Legacy Query Path Information call for lookup to old servers such |
3133 | as Win9x/WinME */ | 3142 | as Win9x/WinME */ |
@@ -3363,6 +3372,9 @@ UnixQPathInfoRetry: | |||
3363 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | 3372 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); |
3364 | 3373 | ||
3365 | if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { | 3374 | if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { |
3375 | cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n" | ||
3376 | "Unix Extensions can be disabled on mount " | ||
3377 | "by specifying the nosfu mount option.")); | ||
3366 | rc = -EIO; /* bad smb */ | 3378 | rc = -EIO; /* bad smb */ |
3367 | } else { | 3379 | } else { |
3368 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 3380 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); |
@@ -3883,12 +3895,10 @@ getDFSRetry: | |||
3883 | pSMB->hdr.Mid = GetNextMid(ses->server); | 3895 | pSMB->hdr.Mid = GetNextMid(ses->server); |
3884 | pSMB->hdr.Tid = ses->ipc_tid; | 3896 | pSMB->hdr.Tid = ses->ipc_tid; |
3885 | pSMB->hdr.Uid = ses->Suid; | 3897 | pSMB->hdr.Uid = ses->Suid; |
3886 | if (ses->capabilities & CAP_STATUS32) { | 3898 | if (ses->capabilities & CAP_STATUS32) |
3887 | pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; | 3899 | pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; |
3888 | } | 3900 | if (ses->capabilities & CAP_DFS) |
3889 | if (ses->capabilities & CAP_DFS) { | ||
3890 | pSMB->hdr.Flags2 |= SMBFLG2_DFS; | 3901 | pSMB->hdr.Flags2 |= SMBFLG2_DFS; |
3891 | } | ||
3892 | 3902 | ||
3893 | if (ses->capabilities & CAP_UNICODE) { | 3903 | if (ses->capabilities & CAP_UNICODE) { |
3894 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 3904 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; |
@@ -4060,10 +4070,6 @@ oldQFSInfoRetry: | |||
4060 | (void **) &pSMBr); | 4070 | (void **) &pSMBr); |
4061 | if (rc) | 4071 | if (rc) |
4062 | return rc; | 4072 | return rc; |
4063 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | ||
4064 | (void **) &pSMBr); | ||
4065 | if (rc) | ||
4066 | return rc; | ||
4067 | 4073 | ||
4068 | params = 2; /* level */ | 4074 | params = 2; /* level */ |
4069 | pSMB->TotalDataCount = 0; | 4075 | pSMB->TotalDataCount = 0; |
@@ -4265,7 +4271,7 @@ QFSAttributeRetry: | |||
4265 | *) (((char *) &pSMBr->hdr.Protocol) + | 4271 | *) (((char *) &pSMBr->hdr.Protocol) + |
4266 | data_offset); | 4272 | data_offset); |
4267 | memcpy(&tcon->fsAttrInfo, response_data, | 4273 | memcpy(&tcon->fsAttrInfo, response_data, |
4268 | sizeof (FILE_SYSTEM_ATTRIBUTE_INFO)); | 4274 | sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); |
4269 | } | 4275 | } |
4270 | } | 4276 | } |
4271 | cifs_buf_release(pSMB); | 4277 | cifs_buf_release(pSMB); |
@@ -4334,7 +4340,7 @@ QFSDeviceRetry: | |||
4334 | (((char *) &pSMBr->hdr.Protocol) + | 4340 | (((char *) &pSMBr->hdr.Protocol) + |
4335 | data_offset); | 4341 | data_offset); |
4336 | memcpy(&tcon->fsDevInfo, response_data, | 4342 | memcpy(&tcon->fsDevInfo, response_data, |
4337 | sizeof (FILE_SYSTEM_DEVICE_INFO)); | 4343 | sizeof(FILE_SYSTEM_DEVICE_INFO)); |
4338 | } | 4344 | } |
4339 | } | 4345 | } |
4340 | cifs_buf_release(pSMB); | 4346 | cifs_buf_release(pSMB); |
@@ -4402,7 +4408,7 @@ QFSUnixRetry: | |||
4402 | *) (((char *) &pSMBr->hdr.Protocol) + | 4408 | *) (((char *) &pSMBr->hdr.Protocol) + |
4403 | data_offset); | 4409 | data_offset); |
4404 | memcpy(&tcon->fsUnixInfo, response_data, | 4410 | memcpy(&tcon->fsUnixInfo, response_data, |
4405 | sizeof (FILE_SYSTEM_UNIX_INFO)); | 4411 | sizeof(FILE_SYSTEM_UNIX_INFO)); |
4406 | } | 4412 | } |
4407 | } | 4413 | } |
4408 | cifs_buf_release(pSMB); | 4414 | cifs_buf_release(pSMB); |
@@ -4612,7 +4618,7 @@ SetEOFRetry: | |||
4612 | strncpy(pSMB->FileName, fileName, name_len); | 4618 | strncpy(pSMB->FileName, fileName, name_len); |
4613 | } | 4619 | } |
4614 | params = 6 + name_len; | 4620 | params = 6 + name_len; |
4615 | data_count = sizeof (struct file_end_of_file_info); | 4621 | data_count = sizeof(struct file_end_of_file_info); |
4616 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4622 | pSMB->MaxParameterCount = cpu_to_le16(2); |
4617 | pSMB->MaxDataCount = cpu_to_le16(4100); | 4623 | pSMB->MaxDataCount = cpu_to_le16(4100); |
4618 | pSMB->MaxSetupCount = 0; | 4624 | pSMB->MaxSetupCount = 0; |
@@ -4800,7 +4806,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, | |||
4800 | 4806 | ||
4801 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | 4807 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; |
4802 | 4808 | ||
4803 | count = sizeof (FILE_BASIC_INFO); | 4809 | count = sizeof(FILE_BASIC_INFO); |
4804 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4810 | pSMB->MaxParameterCount = cpu_to_le16(2); |
4805 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ | 4811 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ |
4806 | pSMB->SetupCount = 1; | 4812 | pSMB->SetupCount = 1; |
@@ -4871,7 +4877,7 @@ SetTimesRetry: | |||
4871 | } | 4877 | } |
4872 | 4878 | ||
4873 | params = 6 + name_len; | 4879 | params = 6 + name_len; |
4874 | count = sizeof (FILE_BASIC_INFO); | 4880 | count = sizeof(FILE_BASIC_INFO); |
4875 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4881 | pSMB->MaxParameterCount = cpu_to_le16(2); |
4876 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ | 4882 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ |
4877 | pSMB->MaxSetupCount = 0; | 4883 | pSMB->MaxSetupCount = 0; |
@@ -4900,7 +4906,7 @@ SetTimesRetry: | |||
4900 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); | 4906 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); |
4901 | pSMB->Reserved4 = 0; | 4907 | pSMB->Reserved4 = 0; |
4902 | pSMB->hdr.smb_buf_length += byte_count; | 4908 | pSMB->hdr.smb_buf_length += byte_count; |
4903 | memcpy(data_offset, data, sizeof (FILE_BASIC_INFO)); | 4909 | memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); |
4904 | pSMB->ByteCount = cpu_to_le16(byte_count); | 4910 | pSMB->ByteCount = cpu_to_le16(byte_count); |
4905 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 4911 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
4906 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 4912 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
@@ -5003,7 +5009,7 @@ setPermsRetry: | |||
5003 | } | 5009 | } |
5004 | 5010 | ||
5005 | params = 6 + name_len; | 5011 | params = 6 + name_len; |
5006 | count = sizeof (FILE_UNIX_BASIC_INFO); | 5012 | count = sizeof(FILE_UNIX_BASIC_INFO); |
5007 | pSMB->MaxParameterCount = cpu_to_le16(2); | 5013 | pSMB->MaxParameterCount = cpu_to_le16(2); |
5008 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ | 5014 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ |
5009 | pSMB->MaxSetupCount = 0; | 5015 | pSMB->MaxSetupCount = 0; |