aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c228
1 files changed, 147 insertions, 81 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f0d9a485d095..9409524e4bf8 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -647,8 +647,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
647 count - 16, 647 count - 16,
648 &server->secType); 648 &server->secType);
649 if (rc == 1) { 649 if (rc == 1) {
650 /* BB Need to fill struct for sessetup here */ 650 rc = 0;
651 rc = -EOPNOTSUPP;
652 } else { 651 } else {
653 rc = -EINVAL; 652 rc = -EINVAL;
654 } 653 }
@@ -699,9 +698,7 @@ int
699CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) 698CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
700{ 699{
701 struct smb_hdr *smb_buffer; 700 struct smb_hdr *smb_buffer;
702 struct smb_hdr *smb_buffer_response; /* BB removeme BB */
703 int rc = 0; 701 int rc = 0;
704 int length;
705 702
706 cFYI(1, ("In tree disconnect")); 703 cFYI(1, ("In tree disconnect"));
707 /* 704 /*
@@ -738,16 +735,12 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
738 if (rc) { 735 if (rc) {
739 up(&tcon->tconSem); 736 up(&tcon->tconSem);
740 return rc; 737 return rc;
741 } else {
742 smb_buffer_response = smb_buffer; /* BB removeme BB */
743 } 738 }
744 rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response, 739
745 &length, 0); 740 rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
746 if (rc) 741 if (rc)
747 cFYI(1, ("Tree disconnect failed %d", rc)); 742 cFYI(1, ("Tree disconnect failed %d", rc));
748 743
749 if (smb_buffer)
750 cifs_small_buf_release(smb_buffer);
751 up(&tcon->tconSem); 744 up(&tcon->tconSem);
752 745
753 /* No need to return error on this operation if tid invalidated and 746 /* No need to return error on this operation if tid invalidated and
@@ -761,10 +754,8 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
761int 754int
762CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) 755CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
763{ 756{
764 struct smb_hdr *smb_buffer_response;
765 LOGOFF_ANDX_REQ *pSMB; 757 LOGOFF_ANDX_REQ *pSMB;
766 int rc = 0; 758 int rc = 0;
767 int length;
768 759
769 cFYI(1, ("In SMBLogoff for session disconnect")); 760 cFYI(1, ("In SMBLogoff for session disconnect"));
770 if (ses) 761 if (ses)
@@ -783,8 +774,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
783 return rc; 774 return rc;
784 } 775 }
785 776
786 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
787
788 if (ses->server) { 777 if (ses->server) {
789 pSMB->hdr.Mid = GetNextMid(ses->server); 778 pSMB->hdr.Mid = GetNextMid(ses->server);
790 779
@@ -796,8 +785,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
796 pSMB->hdr.Uid = ses->Suid; 785 pSMB->hdr.Uid = ses->Suid;
797 786
798 pSMB->AndXCommand = 0xFF; 787 pSMB->AndXCommand = 0xFF;
799 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 788 rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
800 smb_buffer_response, &length, 0);
801 if (ses->server) { 789 if (ses->server) {
802 atomic_dec(&ses->server->socketUseCount); 790 atomic_dec(&ses->server->socketUseCount);
803 if (atomic_read(&ses->server->socketUseCount) == 0) { 791 if (atomic_read(&ses->server->socketUseCount) == 0) {
@@ -808,7 +796,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
808 } 796 }
809 } 797 }
810 up(&ses->sesSem); 798 up(&ses->sesSem);
811 cifs_small_buf_release(pSMB);
812 799
813 /* if session dead then we do not need to do ulogoff, 800 /* if session dead then we do not need to do ulogoff,
814 since server closed smb session, no sense reporting 801 since server closed smb session, no sense reporting
@@ -1256,7 +1243,7 @@ OldOpenRetry:
1256 pSMB->ByteCount = cpu_to_le16(count); 1243 pSMB->ByteCount = cpu_to_le16(count);
1257 /* long_op set to 1 to allow for oplock break timeouts */ 1244 /* long_op set to 1 to allow for oplock break timeouts */
1258 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1245 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1259 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1246 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
1260 cifs_stats_inc(&tcon->num_opens); 1247 cifs_stats_inc(&tcon->num_opens);
1261 if (rc) { 1248 if (rc) {
1262 cFYI(1, ("Error in Open = %d", rc)); 1249 cFYI(1, ("Error in Open = %d", rc));
@@ -1369,7 +1356,7 @@ openRetry:
1369 pSMB->ByteCount = cpu_to_le16(count); 1356 pSMB->ByteCount = cpu_to_le16(count);
1370 /* long_op set to 1 to allow for oplock break timeouts */ 1357 /* long_op set to 1 to allow for oplock break timeouts */
1371 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1358 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1372 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1359 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
1373 cifs_stats_inc(&tcon->num_opens); 1360 cifs_stats_inc(&tcon->num_opens);
1374 if (rc) { 1361 if (rc) {
1375 cFYI(1, ("Error in Open = %d", rc)); 1362 cFYI(1, ("Error in Open = %d", rc));
@@ -1447,7 +1434,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1447 iov[0].iov_base = (char *)pSMB; 1434 iov[0].iov_base = (char *)pSMB;
1448 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1435 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1449 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 1436 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1450 &resp_buf_type, 0 /* not long op */, 1 /* log err */ ); 1437 &resp_buf_type, CIFS_STD_OP | CIFS_LOG_ERROR);
1451 cifs_stats_inc(&tcon->num_reads); 1438 cifs_stats_inc(&tcon->num_reads);
1452 pSMBr = (READ_RSP *)iov[0].iov_base; 1439 pSMBr = (READ_RSP *)iov[0].iov_base;
1453 if (rc) { 1440 if (rc) {
@@ -1666,7 +1653,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1666 1653
1667 1654
1668 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 1655 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
1669 long_op, 0 /* do not log STATUS code */ ); 1656 long_op);
1670 cifs_stats_inc(&tcon->num_writes); 1657 cifs_stats_inc(&tcon->num_writes);
1671 if (rc) { 1658 if (rc) {
1672 cFYI(1, ("Send error Write2 = %d", rc)); 1659 cFYI(1, ("Send error Write2 = %d", rc));
@@ -1708,7 +1695,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1708 int timeout = 0; 1695 int timeout = 0;
1709 __u16 count; 1696 __u16 count;
1710 1697
1711 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d", waitFlag, numLock)); 1698 cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock));
1712 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1699 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1713 1700
1714 if (rc) 1701 if (rc)
@@ -1717,10 +1704,10 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1717 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ 1704 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
1718 1705
1719 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1706 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1720 timeout = -1; /* no response expected */ 1707 timeout = CIFS_ASYNC_OP; /* no response expected */
1721 pSMB->Timeout = 0; 1708 pSMB->Timeout = 0;
1722 } else if (waitFlag == TRUE) { 1709 } else if (waitFlag == TRUE) {
1723 timeout = 3; /* blocking operation, no timeout */ 1710 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1724 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 1711 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1725 } else { 1712 } else {
1726 pSMB->Timeout = 0; 1713 pSMB->Timeout = 0;
@@ -1750,15 +1737,16 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1750 if (waitFlag) { 1737 if (waitFlag) {
1751 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1738 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1752 (struct smb_hdr *) pSMBr, &bytes_returned); 1739 (struct smb_hdr *) pSMBr, &bytes_returned);
1740 cifs_small_buf_release(pSMB);
1753 } else { 1741 } else {
1754 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1742 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
1755 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1743 timeout);
1744 /* SMB buffer freed by function above */
1756 } 1745 }
1757 cifs_stats_inc(&tcon->num_locks); 1746 cifs_stats_inc(&tcon->num_locks);
1758 if (rc) { 1747 if (rc) {
1759 cFYI(1, ("Send error in Lock = %d", rc)); 1748 cFYI(1, ("Send error in Lock = %d", rc));
1760 } 1749 }
1761 cifs_small_buf_release(pSMB);
1762 1750
1763 /* Note: On -EAGAIN error only caller can retry on handle based calls 1751 /* Note: On -EAGAIN error only caller can retry on handle based calls
1764 since file handle passed in no longer valid */ 1752 since file handle passed in no longer valid */
@@ -1777,7 +1765,9 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1777 int rc = 0; 1765 int rc = 0;
1778 int timeout = 0; 1766 int timeout = 0;
1779 int bytes_returned = 0; 1767 int bytes_returned = 0;
1768 int resp_buf_type = 0;
1780 __u16 params, param_offset, offset, byte_count, count; 1769 __u16 params, param_offset, offset, byte_count, count;
1770 struct kvec iov[1];
1781 1771
1782 cFYI(1, ("Posix Lock")); 1772 cFYI(1, ("Posix Lock"));
1783 1773
@@ -1819,7 +1809,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1819 1809
1820 parm_data->lock_type = cpu_to_le16(lock_type); 1810 parm_data->lock_type = cpu_to_le16(lock_type);
1821 if (waitFlag) { 1811 if (waitFlag) {
1822 timeout = 3; /* blocking operation, no timeout */ 1812 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1823 parm_data->lock_flags = cpu_to_le16(1); 1813 parm_data->lock_flags = cpu_to_le16(1);
1824 pSMB->Timeout = cpu_to_le32(-1); 1814 pSMB->Timeout = cpu_to_le32(-1);
1825 } else 1815 } else
@@ -1839,8 +1829,13 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1839 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1829 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1840 (struct smb_hdr *) pSMBr, &bytes_returned); 1830 (struct smb_hdr *) pSMBr, &bytes_returned);
1841 } else { 1831 } else {
1842 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1832 iov[0].iov_base = (char *)pSMB;
1843 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1833 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1834 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1835 &resp_buf_type, timeout);
1836 pSMB = NULL; /* request buf already freed by SendReceive2. Do
1837 not try to free it twice below on exit */
1838 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
1844 } 1839 }
1845 1840
1846 if (rc) { 1841 if (rc) {
@@ -1875,6 +1870,11 @@ plk_err_exit:
1875 if (pSMB) 1870 if (pSMB)
1876 cifs_small_buf_release(pSMB); 1871 cifs_small_buf_release(pSMB);
1877 1872
1873 if (resp_buf_type == CIFS_SMALL_BUFFER)
1874 cifs_small_buf_release(iov[0].iov_base);
1875 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1876 cifs_buf_release(iov[0].iov_base);
1877
1878 /* Note: On -EAGAIN error only caller can retry on handle based calls 1878 /* Note: On -EAGAIN error only caller can retry on handle based calls
1879 since file handle passed in no longer valid */ 1879 since file handle passed in no longer valid */
1880 1880
@@ -1887,8 +1887,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1887{ 1887{
1888 int rc = 0; 1888 int rc = 0;
1889 CLOSE_REQ *pSMB = NULL; 1889 CLOSE_REQ *pSMB = NULL;
1890 CLOSE_RSP *pSMBr = NULL;
1891 int bytes_returned;
1892 cFYI(1, ("In CIFSSMBClose")); 1890 cFYI(1, ("In CIFSSMBClose"));
1893 1891
1894/* do not retry on dead session on close */ 1892/* do not retry on dead session on close */
@@ -1898,13 +1896,10 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1898 if (rc) 1896 if (rc)
1899 return rc; 1897 return rc;
1900 1898
1901 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
1902
1903 pSMB->FileID = (__u16) smb_file_id; 1899 pSMB->FileID = (__u16) smb_file_id;
1904 pSMB->LastWriteTime = 0xFFFFFFFF; 1900 pSMB->LastWriteTime = 0xFFFFFFFF;
1905 pSMB->ByteCount = 0; 1901 pSMB->ByteCount = 0;
1906 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1902 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
1907 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1908 cifs_stats_inc(&tcon->num_closes); 1903 cifs_stats_inc(&tcon->num_closes);
1909 if (rc) { 1904 if (rc) {
1910 if (rc != -EINTR) { 1905 if (rc != -EINTR) {
@@ -1913,8 +1908,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1913 } 1908 }
1914 } 1909 }
1915 1910
1916 cifs_small_buf_release(pSMB);
1917
1918 /* Since session is dead, file will be closed on server already */ 1911 /* Since session is dead, file will be closed on server already */
1919 if (rc == -EAGAIN) 1912 if (rc == -EAGAIN)
1920 rc = 0; 1913 rc = 0;
@@ -2486,6 +2479,7 @@ querySymLinkRetry:
2486 return rc; 2479 return rc;
2487} 2480}
2488 2481
2482#ifdef CONFIG_CIFS_EXPERIMENTAL
2489/* Initialize NT TRANSACT SMB into small smb request buffer. 2483/* Initialize NT TRANSACT SMB into small smb request buffer.
2490 This assumes that all NT TRANSACTS that we init here have 2484 This assumes that all NT TRANSACTS that we init here have
2491 total parm and data under about 400 bytes (to fit in small cifs 2485 total parm and data under about 400 bytes (to fit in small cifs
@@ -2494,7 +2488,7 @@ querySymLinkRetry:
2494 MaxSetupCount (size of returned setup area) and 2488 MaxSetupCount (size of returned setup area) and
2495 MaxParameterCount (returned parms size) must be set by caller */ 2489 MaxParameterCount (returned parms size) must be set by caller */
2496static int 2490static int
2497smb_init_ntransact(const __u16 sub_command, const int setup_count, 2491smb_init_nttransact(const __u16 sub_command, const int setup_count,
2498 const int parm_len, struct cifsTconInfo *tcon, 2492 const int parm_len, struct cifsTconInfo *tcon,
2499 void **ret_buf) 2493 void **ret_buf)
2500{ 2494{
@@ -2525,12 +2519,15 @@ smb_init_ntransact(const __u16 sub_command, const int setup_count,
2525 2519
2526static int 2520static int
2527validate_ntransact(char *buf, char **ppparm, char **ppdata, 2521validate_ntransact(char *buf, char **ppparm, char **ppdata,
2528 int *pdatalen, int *pparmlen) 2522 __u32 *pparmlen, __u32 *pdatalen)
2529{ 2523{
2530 char *end_of_smb; 2524 char *end_of_smb;
2531 __u32 data_count, data_offset, parm_count, parm_offset; 2525 __u32 data_count, data_offset, parm_count, parm_offset;
2532 struct smb_com_ntransact_rsp *pSMBr; 2526 struct smb_com_ntransact_rsp *pSMBr;
2533 2527
2528 *pdatalen = 0;
2529 *pparmlen = 0;
2530
2534 if (buf == NULL) 2531 if (buf == NULL)
2535 return -EINVAL; 2532 return -EINVAL;
2536 2533
@@ -2567,8 +2564,11 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
2567 cFYI(1, ("parm count and data count larger than SMB")); 2564 cFYI(1, ("parm count and data count larger than SMB"));
2568 return -EINVAL; 2565 return -EINVAL;
2569 } 2566 }
2567 *pdatalen = data_count;
2568 *pparmlen = parm_count;
2570 return 0; 2569 return 0;
2571} 2570}
2571#endif /* CIFS_EXPERIMENTAL */
2572 2572
2573int 2573int
2574CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2574CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3067,8 +3067,7 @@ GetExtAttrOut:
3067/* 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 */
3068int 3068int
3069CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3069CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3070 /* BB fix up return info */ char *acl_inf, const int buflen, 3070 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3071 const int acl_type)
3072{ 3071{
3073 int rc = 0; 3072 int rc = 0;
3074 int buf_type = 0; 3073 int buf_type = 0;
@@ -3077,7 +3076,10 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3077 3076
3078 cFYI(1, ("GetCifsACL")); 3077 cFYI(1, ("GetCifsACL"));
3079 3078
3080 rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3079 *pbuflen = 0;
3080 *acl_inf = NULL;
3081
3082 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3081 8 /* parm len */, tcon, (void **) &pSMB); 3083 8 /* parm len */, tcon, (void **) &pSMB);
3082 if (rc) 3084 if (rc)
3083 return rc; 3085 return rc;
@@ -3094,39 +3096,57 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3094 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 3096 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
3095 3097
3096 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3098 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3097 0 /* not long op */, 0 /* do not log STATUS codes */ ); 3099 CIFS_STD_OP);
3098 cifs_stats_inc(&tcon->num_acl_get); 3100 cifs_stats_inc(&tcon->num_acl_get);
3099 if (rc) { 3101 if (rc) {
3100 cFYI(1, ("Send error in QuerySecDesc = %d", rc)); 3102 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
3101 } else { /* decode response */ 3103 } else { /* decode response */
3102 struct cifs_ntsd *psec_desc;
3103 __le32 * parm; 3104 __le32 * parm;
3104 int parm_len; 3105 __u32 parm_len;
3105 int data_len; 3106 __u32 acl_len;
3106 int acl_len;
3107 struct smb_com_ntransact_rsp *pSMBr; 3107 struct smb_com_ntransact_rsp *pSMBr;
3108 char *pdata;
3108 3109
3109/* validate_nttransact */ 3110/* validate_nttransact */
3110 rc = validate_ntransact(iov[0].iov_base, (char **)&parm, 3111 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3111 (char **)&psec_desc, 3112 &pdata, &parm_len, pbuflen);
3112 &parm_len, &data_len);
3113 if (rc) 3113 if (rc)
3114 goto qsec_out; 3114 goto qsec_out;
3115 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; 3115 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3116 3116
3117 cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc)); 3117 cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, *acl_inf));
3118 3118
3119 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3119 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3120 rc = -EIO; /* bad smb */ 3120 rc = -EIO; /* bad smb */
3121 *pbuflen = 0;
3121 goto qsec_out; 3122 goto qsec_out;
3122 } 3123 }
3123 3124
3124/* BB check that data area is minimum length and as big as acl_len */ 3125/* BB check that data area is minimum length and as big as acl_len */
3125 3126
3126 acl_len = le32_to_cpu(*parm); 3127 acl_len = le32_to_cpu(*parm);
3127 /* BB check if (acl_len > bufsize) */ 3128 if (acl_len != *pbuflen) {
3129 cERROR(1, ("acl length %d does not match %d",
3130 acl_len, *pbuflen));
3131 if (*pbuflen > acl_len)
3132 *pbuflen = acl_len;
3133 }
3128 3134
3129 parse_sec_desc(psec_desc, acl_len); 3135 /* check if buffer is big enough for the acl
3136 header followed by the smallest SID */
3137 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3138 (*pbuflen >= 64 * 1024)) {
3139 cERROR(1, ("bad acl length %d", *pbuflen));
3140 rc = -EINVAL;
3141 *pbuflen = 0;
3142 } else {
3143 *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3144 if (*acl_inf == NULL) {
3145 *pbuflen = 0;
3146 rc = -ENOMEM;
3147 }
3148 memcpy(*acl_inf, pdata, *pbuflen);
3149 }
3130 } 3150 }
3131qsec_out: 3151qsec_out:
3132 if (buf_type == CIFS_SMALL_BUFFER) 3152 if (buf_type == CIFS_SMALL_BUFFER)
@@ -3136,6 +3156,71 @@ qsec_out:
3136/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 3156/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3137 return rc; 3157 return rc;
3138} 3158}
3159
3160int
3161CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3162 struct cifs_ntsd *pntsd, __u32 acllen)
3163{
3164 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3165 int rc = 0;
3166 int bytes_returned = 0;
3167 SET_SEC_DESC_REQ *pSMB = NULL;
3168 NTRANSACT_RSP *pSMBr = NULL;
3169
3170setCifsAclRetry:
3171 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
3172 (void **) &pSMBr);
3173 if (rc)
3174 return (rc);
3175
3176 pSMB->MaxSetupCount = 0;
3177 pSMB->Reserved = 0;
3178
3179 param_count = 8;
3180 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3181 data_count = acllen;
3182 data_offset = param_offset + param_count;
3183 byte_count = 3 /* pad */ + param_count;
3184
3185 pSMB->DataCount = cpu_to_le32(data_count);
3186 pSMB->TotalDataCount = pSMB->DataCount;
3187 pSMB->MaxParameterCount = cpu_to_le32(4);
3188 pSMB->MaxDataCount = cpu_to_le32(16384);
3189 pSMB->ParameterCount = cpu_to_le32(param_count);
3190 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3191 pSMB->TotalParameterCount = pSMB->ParameterCount;
3192 pSMB->DataOffset = cpu_to_le32(data_offset);
3193 pSMB->SetupCount = 0;
3194 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3195 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3196
3197 pSMB->Fid = fid; /* file handle always le */
3198 pSMB->Reserved2 = 0;
3199 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_DACL);
3200
3201 if (pntsd && acllen) {
3202 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3203 (char *) pntsd,
3204 acllen);
3205 pSMB->hdr.smb_buf_length += (byte_count + data_count);
3206
3207 } else
3208 pSMB->hdr.smb_buf_length += byte_count;
3209
3210 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3211 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3212
3213 cFYI(1, ("SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc));
3214 if (rc)
3215 cFYI(1, ("Set CIFS ACL returned %d", rc));
3216 cifs_buf_release(pSMB);
3217
3218 if (rc == -EAGAIN)
3219 goto setCifsAclRetry;
3220
3221 return (rc);
3222}
3223
3139#endif /* CONFIG_CIFS_EXPERIMENTAL */ 3224#endif /* CONFIG_CIFS_EXPERIMENTAL */
3140 3225
3141/* Legacy Query Path Information call for lookup to old servers such 3226/* Legacy Query Path Information call for lookup to old servers such
@@ -3381,7 +3466,7 @@ UnixQPathInfoRetry:
3381 memcpy((char *) pFindData, 3466 memcpy((char *) pFindData,
3382 (char *) &pSMBr->hdr.Protocol + 3467 (char *) &pSMBr->hdr.Protocol +
3383 data_offset, 3468 data_offset,
3384 sizeof (FILE_UNIX_BASIC_INFO)); 3469 sizeof(FILE_UNIX_BASIC_INFO));
3385 } 3470 }
3386 } 3471 }
3387 cifs_buf_release(pSMB); 3472 cifs_buf_release(pSMB);
@@ -3649,7 +3734,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3649 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); 3734 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
3650 pSMB->SearchHandle = searchHandle; /* always kept as le */ 3735 pSMB->SearchHandle = searchHandle; /* always kept as le */
3651 pSMB->SearchCount = 3736 pSMB->SearchCount =
3652 cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO)); 3737 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
3653 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 3738 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3654 pSMB->ResumeKey = psrch_inf->resume_key; 3739 pSMB->ResumeKey = psrch_inf->resume_key;
3655 pSMB->SearchFlags = 3740 pSMB->SearchFlags =
@@ -3737,8 +3822,6 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3737{ 3822{
3738 int rc = 0; 3823 int rc = 0;
3739 FINDCLOSE_REQ *pSMB = NULL; 3824 FINDCLOSE_REQ *pSMB = NULL;
3740 CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */
3741 int bytes_returned;
3742 3825
3743 cFYI(1, ("In CIFSSMBFindClose")); 3826 cFYI(1, ("In CIFSSMBFindClose"));
3744 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 3827 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
@@ -3750,16 +3833,13 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3750 if (rc) 3833 if (rc)
3751 return rc; 3834 return rc;
3752 3835
3753 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
3754 pSMB->FileID = searchHandle; 3836 pSMB->FileID = searchHandle;
3755 pSMB->ByteCount = 0; 3837 pSMB->ByteCount = 0;
3756 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3838 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
3757 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3758 if (rc) { 3839 if (rc) {
3759 cERROR(1, ("Send error in FindClose = %d", rc)); 3840 cERROR(1, ("Send error in FindClose = %d", rc));
3760 } 3841 }
3761 cifs_stats_inc(&tcon->num_fclose); 3842 cifs_stats_inc(&tcon->num_fclose);
3762 cifs_small_buf_release(pSMB);
3763 3843
3764 /* Since session is dead, search handle closed on server already */ 3844 /* Since session is dead, search handle closed on server already */
3765 if (rc == -EAGAIN) 3845 if (rc == -EAGAIN)
@@ -4331,7 +4411,7 @@ QFSDeviceRetry:
4331 } else { /* decode response */ 4411 } else { /* decode response */
4332 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4412 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4333 4413
4334 if (rc || (pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))) 4414 if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO)))
4335 rc = -EIO; /* bad smb */ 4415 rc = -EIO; /* bad smb */
4336 else { 4416 else {
4337 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4417 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4681,11 +4761,9 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4681 __u16 fid, __u32 pid_of_opener, int SetAllocation) 4761 __u16 fid, __u32 pid_of_opener, int SetAllocation)
4682{ 4762{
4683 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4763 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4684 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
4685 char *data_offset; 4764 char *data_offset;
4686 struct file_end_of_file_info *parm_data; 4765 struct file_end_of_file_info *parm_data;
4687 int rc = 0; 4766 int rc = 0;
4688 int bytes_returned = 0;
4689 __u16 params, param_offset, offset, byte_count, count; 4767 __u16 params, param_offset, offset, byte_count, count;
4690 4768
4691 cFYI(1, ("SetFileSize (via SetFileInfo) %lld", 4769 cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
@@ -4695,8 +4773,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4695 if (rc) 4773 if (rc)
4696 return rc; 4774 return rc;
4697 4775
4698 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
4699
4700 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 4776 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4701 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 4777 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
4702 4778
@@ -4747,17 +4823,13 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4747 pSMB->Reserved4 = 0; 4823 pSMB->Reserved4 = 0;
4748 pSMB->hdr.smb_buf_length += byte_count; 4824 pSMB->hdr.smb_buf_length += byte_count;
4749 pSMB->ByteCount = cpu_to_le16(byte_count); 4825 pSMB->ByteCount = cpu_to_le16(byte_count);
4750 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4826 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4751 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4752 if (rc) { 4827 if (rc) {
4753 cFYI(1, 4828 cFYI(1,
4754 ("Send error in SetFileInfo (SetFileSize) = %d", 4829 ("Send error in SetFileInfo (SetFileSize) = %d",
4755 rc)); 4830 rc));
4756 } 4831 }
4757 4832
4758 if (pSMB)
4759 cifs_small_buf_release(pSMB);
4760
4761 /* Note: On -EAGAIN error only caller can retry on handle based calls 4833 /* Note: On -EAGAIN error only caller can retry on handle based calls
4762 since file handle passed in no longer valid */ 4834 since file handle passed in no longer valid */
4763 4835
@@ -4775,10 +4847,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4775 const FILE_BASIC_INFO *data, __u16 fid) 4847 const FILE_BASIC_INFO *data, __u16 fid)
4776{ 4848{
4777 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4849 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4778 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
4779 char *data_offset; 4850 char *data_offset;
4780 int rc = 0; 4851 int rc = 0;
4781 int bytes_returned = 0;
4782 __u16 params, param_offset, offset, byte_count, count; 4852 __u16 params, param_offset, offset, byte_count, count;
4783 4853
4784 cFYI(1, ("Set Times (via SetFileInfo)")); 4854 cFYI(1, ("Set Times (via SetFileInfo)"));
@@ -4787,8 +4857,6 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4787 if (rc) 4857 if (rc)
4788 return rc; 4858 return rc;
4789 4859
4790 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
4791
4792 /* At this point there is no need to override the current pid 4860 /* At this point there is no need to override the current pid
4793 with the pid of the opener, but that could change if we someday 4861 with the pid of the opener, but that could change if we someday
4794 use an existing handle (rather than opening one on the fly) */ 4862 use an existing handle (rather than opening one on the fly) */
@@ -4828,14 +4896,11 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4828 pSMB->hdr.smb_buf_length += byte_count; 4896 pSMB->hdr.smb_buf_length += byte_count;
4829 pSMB->ByteCount = cpu_to_le16(byte_count); 4897 pSMB->ByteCount = cpu_to_le16(byte_count);
4830 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 4898 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
4831 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4899 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4832 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4833 if (rc) { 4900 if (rc) {
4834 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc)); 4901 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
4835 } 4902 }
4836 4903
4837 cifs_small_buf_release(pSMB);
4838
4839 /* Note: On -EAGAIN error only caller can retry on handle based calls 4904 /* Note: On -EAGAIN error only caller can retry on handle based calls
4840 since file handle passed in no longer valid */ 4905 since file handle passed in no longer valid */
4841 4906
@@ -5126,7 +5191,8 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5126 pSMB->ByteCount = 0; 5191 pSMB->ByteCount = 0;
5127 5192
5128 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5193 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5129 (struct smb_hdr *) pSMBr, &bytes_returned, -1); 5194 (struct smb_hdr *)pSMBr, &bytes_returned,
5195 CIFS_ASYNC_OP);
5130 if (rc) { 5196 if (rc) {
5131 cFYI(1, ("Error in Notify = %d", rc)); 5197 cFYI(1, ("Error in Notify = %d", rc));
5132 } else { 5198 } else {
@@ -5498,7 +5564,7 @@ SetEARetry:
5498 else 5564 else
5499 name_len = strnlen(ea_name, 255); 5565 name_len = strnlen(ea_name, 255);
5500 5566
5501 count = sizeof(*parm_data) + ea_value_len + name_len + 1; 5567 count = sizeof(*parm_data) + ea_value_len + name_len;
5502 pSMB->MaxParameterCount = cpu_to_le16(2); 5568 pSMB->MaxParameterCount = cpu_to_le16(2);
5503 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ 5569 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */
5504 pSMB->MaxSetupCount = 0; 5570 pSMB->MaxSetupCount = 0;