aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-01-12 18:44:21 -0500
committerSteve French <sfrench@us.ibm.com>2006-01-12 18:44:21 -0500
commit0a4b92c05ed02ad7abdd165823eaf4bbcb33ae5c (patch)
treeb9f82422eaa28c88edc6b92e55d9ff57939b865f
parent94bc2be31a01a3055ec94176e595dfe208e92d3b (diff)
[CIFS] Add worker function for Get ACL cifs style
Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/CHANGES4
-rw-r--r--fs/cifs/cifs_fs_sb.h5
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifspdu.h89
-rw-r--r--fs/cifs/cifsproto.h3
-rw-r--r--fs/cifs/cifssmb.c179
-rw-r--r--fs/cifs/connect.c7
-rw-r--r--fs/cifs/transport.c1
-rw-r--r--fs/cifs/xattr.c22
9 files changed, 292 insertions, 20 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 1d2137561c55..c7995c96f069 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,7 +1,9 @@
1Version 1.40 1Version 1.40
2------------ 2------------
3Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance 3Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
4of readpages by eliminating one extra memcpy. 4of readpages by eliminating one extra memcpy. Allow update of file size
5from remote server even if file is open for write as long as mount is
6directio.
5 7
6Version 1.39 8Version 1.39
7------------ 9------------
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index f799f6f0e729..ad58eb0c4d6d 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -24,9 +24,10 @@
24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ 24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ 25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
26#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ 26#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
27#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ 27#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
28#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ 28#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
29#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ 29#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */
30#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */
30 31
31struct cifs_sb_info { 32struct cifs_sb_info {
32 struct cifsTconInfo *tcon; /* primary mount */ 33 struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 862e403ff211..7bed27601ce5 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -233,6 +233,8 @@ struct cifsTconInfo {
233 atomic_t num_hardlinks; 233 atomic_t num_hardlinks;
234 atomic_t num_symlinks; 234 atomic_t num_symlinks;
235 atomic_t num_locks; 235 atomic_t num_locks;
236 atomic_t num_acl_get;
237 atomic_t num_acl_set;
236#ifdef CONFIG_CIFS_STATS2 238#ifdef CONFIG_CIFS_STATS2
237 unsigned long long time_writes; 239 unsigned long long time_writes;
238 unsigned long long time_reads; 240 unsigned long long time_reads;
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 3c09fb9cc569..cc2471094ca5 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -528,7 +528,7 @@ typedef union smb_com_session_setup_andx {
528 /* STRING PrimaryDomain */ 528 /* STRING PrimaryDomain */
529 /* STRING NativeOS */ 529 /* STRING NativeOS */
530 /* STRING NativeLanMan */ 530 /* STRING NativeLanMan */
531 } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) request format */ 531 } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) req format */
532 532
533 struct { /* default (NTLM) response format */ 533 struct { /* default (NTLM) response format */
534 struct smb_hdr hdr; /* wct = 3 */ 534 struct smb_hdr hdr; /* wct = 3 */
@@ -540,7 +540,7 @@ typedef union smb_com_session_setup_andx {
540 unsigned char NativeOS[1]; /* followed by */ 540 unsigned char NativeOS[1]; /* followed by */
541/* unsigned char * NativeLanMan; */ 541/* unsigned char * NativeLanMan; */
542/* unsigned char * PrimaryDomain; */ 542/* unsigned char * PrimaryDomain; */
543 } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response format */ 543 } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response */
544} __attribute__((packed)) SESSION_SETUP_ANDX; 544} __attribute__((packed)) SESSION_SETUP_ANDX;
545 545
546#define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" 546#define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
@@ -1007,10 +1007,49 @@ typedef struct smb_com_setattr_rsp {
1007 1007
1008/* empty wct response to setattr */ 1008/* empty wct response to setattr */
1009 1009
1010/***************************************************/ 1010/*******************************************************/
1011/* NT Transact structure defintions follow */ 1011/* NT Transact structure defintions follow */
1012/* Currently only ioctl and notify are implemented */ 1012/* Currently only ioctl, acl (get security descriptor) */
1013/***************************************************/ 1013/* and notify are implemented */
1014/*******************************************************/
1015typedef struct smb_com_ntransact_req {
1016 struct smb_hdr hdr; /* wct >= 19 */
1017 __u8 MaxSetupCount;
1018 __u16 Reserved;
1019 __le32 TotalParameterCount;
1020 __le32 TotalDataCount;
1021 __le32 MaxParameterCount;
1022 __le32 MaxDataCount;
1023 __le32 ParameterCount;
1024 __le32 ParameterOffset;
1025 __le32 DataCount;
1026 __le32 DataOffset;
1027 __u8 SetupCount; /* four setup words follow subcommand */
1028 /* SNIA spec incorrectly included spurious pad here */
1029 __le16 SubCommand; /* 2 = IOCTL/FSCTL */
1030 /* SetupCount words follow then */
1031 __le16 ByteCount;
1032 __u8 Pad[3];
1033 __u8 Parms[0];
1034} __attribute__((packed)) NTRANSACT_REQ;
1035
1036typedef struct smb_com_ntransact_rsp {
1037 struct smb_hdr hdr; /* wct = 18 */
1038 __u8 Reserved[3];
1039 __le32 TotalParameterCount;
1040 __le32 TotalDataCount;
1041 __le32 ParameterCount;
1042 __le32 ParameterOffset;
1043 __le32 ParameterDisplacement;
1044 __le32 DataCount;
1045 __le32 DataOffset;
1046 __le32 DataDisplacement;
1047 __u8 SetupCount; /* 0 */
1048 __u16 ByteCount;
1049 /* __u8 Pad[3]; */
1050 /* parms and data follow */
1051} __attribute__((packed)) NTRANSACT_RSP;
1052
1014typedef struct smb_com_transaction_ioctl_req { 1053typedef struct smb_com_transaction_ioctl_req {
1015 struct smb_hdr hdr; /* wct = 23 */ 1054 struct smb_hdr hdr; /* wct = 23 */
1016 __u8 MaxSetupCount; 1055 __u8 MaxSetupCount;
@@ -1025,11 +1064,11 @@ typedef struct smb_com_transaction_ioctl_req {
1025 __le32 DataOffset; 1064 __le32 DataOffset;
1026 __u8 SetupCount; /* four setup words follow subcommand */ 1065 __u8 SetupCount; /* four setup words follow subcommand */
1027 /* SNIA spec incorrectly included spurious pad here */ 1066 /* SNIA spec incorrectly included spurious pad here */
1028 __le16 SubCommand;/* 2 = IOCTL/FSCTL */ 1067 __le16 SubCommand; /* 2 = IOCTL/FSCTL */
1029 __le32 FunctionCode; 1068 __le32 FunctionCode;
1030 __u16 Fid; 1069 __u16 Fid;
1031 __u8 IsFsctl; /* 1 = File System Control, 0 = device control (IOCTL)*/ 1070 __u8 IsFsctl; /* 1 = File System Control 0 = device control (IOCTL) */
1032 __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS share)*/ 1071 __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS) */
1033 __le16 ByteCount; 1072 __le16 ByteCount;
1034 __u8 Pad[3]; 1073 __u8 Pad[3];
1035 __u8 Data[1]; 1074 __u8 Data[1];
@@ -1049,9 +1088,35 @@ typedef struct smb_com_transaction_ioctl_rsp {
1049 __u8 SetupCount; /* 1 */ 1088 __u8 SetupCount; /* 1 */
1050 __le16 ReturnedDataLen; 1089 __le16 ReturnedDataLen;
1051 __u16 ByteCount; 1090 __u16 ByteCount;
1052 __u8 Pad[3];
1053} __attribute__((packed)) TRANSACT_IOCTL_RSP; 1091} __attribute__((packed)) TRANSACT_IOCTL_RSP;
1054 1092
1093#define CIFS_ACL_OWNER 1
1094#define CIFS_ACL_GROUP 2
1095#define CIFS_ACL_DACL 4
1096#define CIFS_ACL_SACL 8
1097
1098typedef struct smb_com_transaction_qsec_req {
1099 struct smb_hdr hdr; /* wct = 19 */
1100 __u8 MaxSetupCount;
1101 __u16 Reserved;
1102 __le32 TotalParameterCount;
1103 __le32 TotalDataCount;
1104 __le32 MaxParameterCount;
1105 __le32 MaxDataCount;
1106 __le32 ParameterCount;
1107 __le32 ParameterOffset;
1108 __le32 DataCount;
1109 __le32 DataOffset;
1110 __u8 SetupCount; /* no setup words follow subcommand */
1111 /* SNIA spec incorrectly included spurious pad here */
1112 __le16 SubCommand; /* 6 = QUERY_SECURITY_DESC */
1113 __le16 ByteCount; /* bcc = 3 + 8 */
1114 __u8 Pad[3];
1115 __u16 Fid;
1116 __u16 Reserved2;
1117 __le32 AclFlags;
1118} __attribute__((packed)) QUERY_SEC_DESC_REQ;
1119
1055typedef struct smb_com_transaction_change_notify_req { 1120typedef struct smb_com_transaction_change_notify_req {
1056 struct smb_hdr hdr; /* wct = 23 */ 1121 struct smb_hdr hdr; /* wct = 23 */
1057 __u8 MaxSetupCount; 1122 __u8 MaxSetupCount;
@@ -1072,10 +1137,12 @@ typedef struct smb_com_transaction_change_notify_req {
1072 __u8 WatchTree; /* 1 = Monitor subdirectories */ 1137 __u8 WatchTree; /* 1 = Monitor subdirectories */
1073 __u8 Reserved2; 1138 __u8 Reserved2;
1074 __le16 ByteCount; 1139 __le16 ByteCount;
1075/* __u8 Pad[3];*/ 1140/* __u8 Pad[3];*/
1076/* __u8 Data[1];*/ 1141/* __u8 Data[1];*/
1077} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; 1142} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
1078 1143
1144/* BB eventually change to use generic ntransact rsp struct
1145 and validation routine */
1079typedef struct smb_com_transaction_change_notify_rsp { 1146typedef struct smb_com_transaction_change_notify_rsp {
1080 struct smb_hdr hdr; /* wct = 18 */ 1147 struct smb_hdr hdr; /* wct = 18 */
1081 __u8 Reserved[3]; 1148 __u8 Reserved[3];
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 8ef0ce47f5b6..3c03aadaff0c 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -299,6 +299,9 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
299 const char *fileName, const char * ea_name, 299 const char *fileName, const char * ea_name,
300 const void * ea_value, const __u16 ea_value_len, 300 const void * ea_value, const __u16 ea_value_len,
301 const struct nls_table *nls_codepage, int remap_special_chars); 301 const struct nls_table *nls_codepage, int remap_special_chars);
302extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
303 __u16 fid, char *acl_inf, const int buflen,
304 const int acl_type /* ACCESS vs. DEFAULT */);
302extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 305extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
303 const unsigned char *searchName, 306 const unsigned char *searchName,
304 char *acl_inf, const int buflen,const int acl_type, 307 char *acl_inf, const int buflen,const int acl_type,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 1620991cd4d2..20300bc9ae77 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1926,6 +1926,90 @@ querySymLinkRetry:
1926 return rc; 1926 return rc;
1927} 1927}
1928 1928
1929/* Initialize NT TRANSACT SMB into small smb request buffer.
1930 This assumes that all NT TRANSACTS that we init here have
1931 total parm and data under about 400 bytes (to fit in small cifs
1932 buffer size), which is the case so far, it easily fits. NB:
1933 Setup words themselves and ByteCount
1934 MaxSetupCount (size of returned setup area) and
1935 MaxParameterCount (returned parms size) must be set by caller */
1936static int
1937smb_init_ntransact(const __u16 sub_command, const int setup_count,
1938 const int parm_len, struct cifsTconInfo *tcon,
1939 void ** ret_buf)
1940{
1941 int rc;
1942 __u32 temp_offset;
1943 struct smb_com_ntransact_req * pSMB;
1944
1945 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
1946 (void **)&pSMB);
1947 if (rc)
1948 return rc;
1949 *ret_buf = (void *)pSMB;
1950 pSMB->Reserved = 0;
1951 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
1952 pSMB->TotalDataCount = 0;
1953 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
1954 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
1955 pSMB->ParameterCount = pSMB->TotalParameterCount;
1956 pSMB->DataCount = pSMB->TotalDataCount;
1957 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
1958 (setup_count * 2) - 4 /* for rfc1001 length itself */;
1959 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
1960 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
1961 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
1962 pSMB->SubCommand = cpu_to_le16(sub_command);
1963 return 0;
1964}
1965
1966static int
1967validate_ntransact(char * buf, char ** ppparm, char ** ppdata,
1968 int * pdatalen, int * pparmlen)
1969{
1970 char * end_of_smb;
1971 __u32 data_count, data_offset, parm_count, parm_offset;
1972 struct smb_com_ntransact_rsp * pSMBr;
1973
1974 if(buf == NULL)
1975 return -EINVAL;
1976
1977 pSMBr = (struct smb_com_ntransact_rsp *)buf;
1978
1979 /* ByteCount was converted from little endian in SendReceive */
1980 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
1981 (char *)&pSMBr->ByteCount;
1982
1983
1984 data_offset = le32_to_cpu(pSMBr->DataOffset);
1985 data_count = le32_to_cpu(pSMBr->DataCount);
1986 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
1987 parm_count = le32_to_cpu(pSMBr->ParameterCount);
1988
1989 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
1990 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
1991
1992 /* should we also check that parm and data areas do not overlap? */
1993 if(*ppparm > end_of_smb) {
1994 cFYI(1,("parms start after end of smb"));
1995 return -EINVAL;
1996 } else if(parm_count + *ppparm > end_of_smb) {
1997 cFYI(1,("parm end after end of smb"));
1998 return -EINVAL;
1999 } else if(*ppdata > end_of_smb) {
2000 cFYI(1,("data starts after end of smb"));
2001 return -EINVAL;
2002 } else if(data_count + *ppdata > end_of_smb) {
2003 cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p",
2004 *ppdata, data_count, (data_count + *ppdata), end_of_smb, pSMBr)); /* BB FIXME */
2005 return -EINVAL;
2006 } else if(parm_count + data_count > pSMBr->ByteCount) {
2007 cFYI(1,("parm count and data count larger than SMB"));
2008 return -EINVAL;
2009 }
2010 return 0;
2011}
2012
1929int 2013int
1930CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2014CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1931 const unsigned char *searchName, 2015 const unsigned char *searchName,
@@ -1948,7 +2032,8 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1948 pSMB->TotalDataCount = 0; 2032 pSMB->TotalDataCount = 0;
1949 pSMB->MaxParameterCount = cpu_to_le32(2); 2033 pSMB->MaxParameterCount = cpu_to_le32(2);
1950 /* BB find exact data count max from sess structure BB */ 2034 /* BB find exact data count max from sess structure BB */
1951 pSMB->MaxDataCount = cpu_to_le32(4000); 2035 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
2036 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
1952 pSMB->MaxSetupCount = 4; 2037 pSMB->MaxSetupCount = 4;
1953 pSMB->Reserved = 0; 2038 pSMB->Reserved = 0;
1954 pSMB->ParameterOffset = 0; 2039 pSMB->ParameterOffset = 0;
@@ -1975,7 +2060,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1975 rc = -EIO; /* bad smb */ 2060 rc = -EIO; /* bad smb */
1976 else { 2061 else {
1977 if(data_count && (data_count < 2048)) { 2062 if(data_count && (data_count < 2048)) {
1978 char * end_of_smb = pSMBr->ByteCount + (char *)&pSMBr->ByteCount; 2063 char * end_of_smb = 2 /* sizeof byte count */ +
2064 pSMBr->ByteCount +
2065 (char *)&pSMBr->ByteCount;
1979 2066
1980 struct reparse_data * reparse_buf = (struct reparse_data *) 2067 struct reparse_data * reparse_buf = (struct reparse_data *)
1981 ((char *)&pSMBr->hdr.Protocol + data_offset); 2068 ((char *)&pSMBr->hdr.Protocol + data_offset);
@@ -2219,6 +2306,7 @@ queryAclRetry:
2219 2306
2220 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2307 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2221 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2308 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2309 cifs_stats_inc(&tcon->num_acl_get);
2222 if (rc) { 2310 if (rc) {
2223 cFYI(1, ("Send error in Query POSIX ACL = %d", rc)); 2311 cFYI(1, ("Send error in Query POSIX ACL = %d", rc));
2224 } else { 2312 } else {
@@ -2406,6 +2494,87 @@ GetExtAttrOut:
2406 2494
2407#endif /* CONFIG_POSIX */ 2495#endif /* CONFIG_POSIX */
2408 2496
2497/* Convert CIFS ACL to POSIX form */
2498static int parse_sec_desc(struct sec_desc * psec_desc, int acl_len)
2499{
2500 CHECK ON OTHER COMPUTER TO SEE IF FORMAT ENCODED IN CIFSPDU.H ALREADY
2501 return 0;
2502}
2503
2504/* Get Security Descriptor (by handle) from remote server for a file or dir */
2505int
2506CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
2507 /* BB fix up return info */ char *acl_inf, const int buflen,
2508 const int acl_type /* ACCESS/DEFAULT not sure implication */)
2509{
2510 int rc = 0;
2511 int buf_type = 0;
2512 QUERY_SEC_DESC_REQ * pSMB;
2513 struct kvec iov[1];
2514
2515 cFYI(1, ("GetCifsACL"));
2516
2517 rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
2518 8 /* parm len */, tcon, (void **) &pSMB);
2519 if (rc)
2520 return rc;
2521
2522 pSMB->MaxParameterCount = cpu_to_le32(4);
2523 /* BB TEST with big acls that might need to be e.g. larger than 16K */
2524 pSMB->MaxSetupCount = 0;
2525 pSMB->Fid = fid; /* file handle always le */
2526 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
2527 CIFS_ACL_DACL);
2528 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
2529 pSMB->hdr.smb_buf_length += 11;
2530 iov[0].iov_base = (char *)pSMB;
2531 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
2532
2533 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
2534 cifs_stats_inc(&tcon->num_acl_get);
2535 if (rc) {
2536 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
2537 } else { /* decode response */
2538 struct sec_desc * psec_desc;
2539 __le32 * parm;
2540 int parm_len;
2541 int data_len;
2542 int acl_len;
2543 struct smb_com_ntransact_rsp * pSMBr;
2544
2545/* validate_nttransact */
2546 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
2547 (char **)&psec_desc,
2548 &parm_len, &data_len);
2549
2550 if(rc)
2551 goto qsec_out;
2552 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
2553
2554 cERROR(1,("smb %p parm %p data %p",pSMBr,parm,psec_desc)); /* BB removeme BB */
2555
2556 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
2557 rc = -EIO; /* bad smb */
2558 goto qsec_out;
2559 }
2560
2561/* BB check that data area is minimum length and as big as acl_len */
2562
2563 acl_len = le32_to_cpu(*(__le32 *)parm);
2564 /* BB check if(acl_len > bufsize) */
2565
2566 parse_sec_desc(psec_desc, acl_len);
2567 }
2568qsec_out:
2569 if(buf_type == CIFS_SMALL_BUFFER)
2570 cifs_small_buf_release(iov[0].iov_base);
2571 else if(buf_type == CIFS_LARGE_BUFFER)
2572 cifs_buf_release(iov[0].iov_base);
2573 cifs_small_buf_release(pSMB);
2574 return rc;
2575}
2576
2577
2409/* Legacy Query Path Information call for lookup to old servers such 2578/* Legacy Query Path Information call for lookup to old servers such
2410 as Win9x/WinME */ 2579 as Win9x/WinME */
2411int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 2580int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
@@ -4304,7 +4473,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
4304{ 4473{
4305 int rc = 0; 4474 int rc = 0;
4306 struct smb_com_transaction_change_notify_req * pSMB = NULL; 4475 struct smb_com_transaction_change_notify_req * pSMB = NULL;
4307 struct smb_com_transaction_change_notify_rsp * pSMBr = NULL; 4476 struct smb_com_ntransaction_change_notify_rsp * pSMBr = NULL;
4308 struct dir_notify_req *dnotify_req; 4477 struct dir_notify_req *dnotify_req;
4309 int bytes_returned; 4478 int bytes_returned;
4310 4479
@@ -4319,6 +4488,10 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
4319 pSMB->MaxParameterCount = cpu_to_le32(2); 4488 pSMB->MaxParameterCount = cpu_to_le32(2);
4320 /* BB find exact data count max from sess structure BB */ 4489 /* BB find exact data count max from sess structure BB */
4321 pSMB->MaxDataCount = 0; /* same in little endian or be */ 4490 pSMB->MaxDataCount = 0; /* same in little endian or be */
4491/* BB VERIFY verify which is correct for above BB */
4492 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
4493 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
4494
4322 pSMB->MaxSetupCount = 4; 4495 pSMB->MaxSetupCount = 4;
4323 pSMB->Reserved = 0; 4496 pSMB->Reserved = 0;
4324 pSMB->ParameterOffset = 0; 4497 pSMB->ParameterOffset = 0;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 45c9d726c002..1817d5313a8a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -76,6 +76,7 @@ struct smb_vol {
76 unsigned setuids:1; 76 unsigned setuids:1;
77 unsigned noperm:1; 77 unsigned noperm:1;
78 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ 78 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
79 unsigned cifs_acl:1;
79 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ 80 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
80 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ 81 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
81 unsigned direct_io:1; 82 unsigned direct_io:1;
@@ -1159,6 +1160,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1159 vol->server_ino = 1; 1160 vol->server_ino = 1;
1160 } else if (strnicmp(data, "noserverino",9) == 0) { 1161 } else if (strnicmp(data, "noserverino",9) == 0) {
1161 vol->server_ino = 0; 1162 vol->server_ino = 0;
1163 } else if (strnicmp(data, "cifsacl",7) == 0) {
1164 vol->cifs_acl = 1;
1165 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1166 vol->cifs_acl = 0;
1162 } else if (strnicmp(data, "acl",3) == 0) { 1167 } else if (strnicmp(data, "acl",3) == 0) {
1163 vol->no_psx_acl = 0; 1168 vol->no_psx_acl = 0;
1164 } else if (strnicmp(data, "noacl",5) == 0) { 1169 } else if (strnicmp(data, "noacl",5) == 0) {
@@ -1806,6 +1811,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1806 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; 1811 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1807 if(volume_info.nobrl) 1812 if(volume_info.nobrl)
1808 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; 1813 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1814 if(volume_info.cifs_acl)
1815 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1809 1816
1810 if(volume_info.direct_io) { 1817 if(volume_info.direct_io) {
1811 cFYI(1,("mounting share using direct i/o")); 1818 cFYI(1,("mounting share using direct i/o"));
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index c96a148c39b2..7b98792150ea 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -489,7 +489,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
489 receive_len, xid)); 489 receive_len, xid));
490 rc = -EIO; 490 rc = -EIO;
491 } else { /* rcvd frame is ok */ 491 } else { /* rcvd frame is ok */
492
493 if (midQ->resp_buf && 492 if (midQ->resp_buf &&
494 (midQ->midState == MID_RESPONSE_RECEIVED)) { 493 (midQ->midState == MID_RESPONSE_RECEIVED)) {
495 494
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index f375f87c7dbd..777e3363c2a4 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -254,7 +254,8 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
254 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, 254 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
255 buf_size, cifs_sb->local_nls, 255 buf_size, cifs_sb->local_nls,
256 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 256 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
257 } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { 257 } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,
258 strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
258#ifdef CONFIG_CIFS_POSIX 259#ifdef CONFIG_CIFS_POSIX
259 if(sb->s_flags & MS_POSIXACL) 260 if(sb->s_flags & MS_POSIXACL)
260 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 261 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
@@ -262,10 +263,27 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
262 cifs_sb->local_nls, 263 cifs_sb->local_nls,
263 cifs_sb->mnt_cifs_flags & 264 cifs_sb->mnt_cifs_flags &
264 CIFS_MOUNT_MAP_SPECIAL_CHR); 265 CIFS_MOUNT_MAP_SPECIAL_CHR);
266/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
267 __u16 fid;
268 int oplock = FALSE;
269 rc = CIFSSMBOpen(xid, pTcon, full_path,
270 FILE_OPEN, GENERIC_READ, 0, &fid,
271 &oplock, NULL, cifs_sb->local_nls,
272 cifs_sb->mnt_cifs_flags &
273 CIFS_MOUNT_MAP_SPECIAL_CHR);
274 if(rc == 0) {
275 rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
276 ea_value, buf_size,
277 ACL_TYPE_ACCESS);
278 CIFSSMBClose(xid, pTcon, fid)
279 }
280 } */ /* BB enable after fixing up return data */
281
265#else 282#else
266 cFYI(1,("query POSIX ACL not supported yet")); 283 cFYI(1,("query POSIX ACL not supported yet"));
267#endif /* CONFIG_CIFS_POSIX */ 284#endif /* CONFIG_CIFS_POSIX */
268 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 285 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,
286 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
269#ifdef CONFIG_CIFS_POSIX 287#ifdef CONFIG_CIFS_POSIX
270 if(sb->s_flags & MS_POSIXACL) 288 if(sb->s_flags & MS_POSIXACL)
271 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 289 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,