diff options
author | Steve French <sfrench@us.ibm.com> | 2007-10-25 17:17:17 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-10-25 17:17:17 -0400 |
commit | 630f3f0c45a80ab907d216191ef4a205c249fa1b (patch) | |
tree | be1fe069ded6df343f978469160b002c5ae67169 | |
parent | 44093ca2fef3c52dc7d186116862d74f9a676e0f (diff) |
[CIFS] acl support part 6
Acked-by: Shirish Pargaonkar <shirishp@us.ibm.com>
CC: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r-- | fs/cifs/cifsacl.c | 91 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 9 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 55 | ||||
-rw-r--r-- | fs/cifs/file.c | 31 | ||||
-rw-r--r-- | fs/cifs/inode.c | 2 | ||||
-rw-r--r-- | fs/cifs/md5.c | 8 | ||||
-rw-r--r-- | fs/cifs/misc.c | 10 | ||||
-rw-r--r-- | fs/cifs/netmisc.c | 12 | ||||
-rw-r--r-- | fs/cifs/smbencrypt.c | 4 | ||||
-rw-r--r-- | fs/cifs/xattr.c | 7 |
10 files changed, 169 insertions, 60 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 154cb8449b9b..14200bd45b30 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -97,7 +97,7 @@ int match_sid(struct cifs_sid *ctsid) | |||
97 | 97 | ||
98 | /* if the two SIDs (roughly equivalent to a UUID for a user or group) are | 98 | /* if the two SIDs (roughly equivalent to a UUID for a user or group) are |
99 | the same returns 1, if they do not match returns 0 */ | 99 | the same returns 1, if they do not match returns 0 */ |
100 | int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid) | 100 | int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) |
101 | { | 101 | { |
102 | int i; | 102 | int i; |
103 | int num_subauth, num_sat, num_saw; | 103 | int num_subauth, num_sat, num_saw; |
@@ -129,28 +129,77 @@ int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid) | |||
129 | return (1); /* sids compare/match */ | 129 | return (1); /* sids compare/match */ |
130 | } | 130 | } |
131 | 131 | ||
132 | void get_mode_from_acl(struct inode * inode, const char * path) | 132 | /* |
133 | change posix mode to reflect permissions | ||
134 | pmode is the existing mode (we only want to overwrite part of this | ||
135 | bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007 | ||
136 | */ | ||
137 | static void access_flags_to_mode(__u32 access_flags, umode_t * pmode, | ||
138 | umode_t bits_to_set) | ||
139 | { | ||
140 | |||
141 | #ifdef CONFIG_CIFS_DEBUG2 | ||
142 | cFYI(1, ("access flags 0x%x mode now 0x%x", access_flags, *pmode); | ||
143 | #endif | ||
144 | |||
145 | return; | ||
146 | } | ||
147 | |||
148 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | ||
149 | |||
150 | void acl_to_uid_mode(struct inode *inode, const char *path) | ||
133 | { | 151 | { |
152 | struct cifsFileInfo *open_file; | ||
153 | int unlock_file = FALSE; | ||
154 | int xid; | ||
155 | int rc = -EIO; | ||
156 | __u16 fid; | ||
157 | struct super_block *sb; | ||
158 | struct cifs_sb_info *cifs_sb; | ||
134 | 159 | ||
135 | cFYI(1, ("get mode from ACL for %s", path)); | 160 | cFYI(1, ("get mode from ACL for %s", path)); |
136 | 161 | ||
137 | if (inode == NULL) | 162 | if (inode == NULL) |
138 | return; | 163 | return; |
139 | 164 | ||
140 | /* find an open readable handle | 165 | xid = GetXid(); |
141 | if handle found | 166 | open_file = find_readable_file(CIFS_I(inode)); |
142 | lock handle | 167 | if (open_file) { |
143 | else open file | 168 | unlock_file = TRUE; |
144 | if no open file can not hurt to check if path is null | 169 | fid = open_file->netfid; |
145 | GetCIFSACL | 170 | } else { |
146 | for all ACEs in ACL { | 171 | int oplock = FALSE; |
147 | if U or G or O | 172 | /* open file */ |
148 | inode->i_mode = parse_ace(file_type, UG or O, ace->perms, inode->i_mode) | 173 | sb = inode->i_sb; |
149 | else continue | 174 | if (sb == NULL) { |
150 | } | 175 | FreeXid(xid); |
151 | if handle open close it | 176 | return; |
152 | else unlock handle */ | 177 | } |
178 | cifs_sb = CIFS_SB(sb); | ||
179 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
180 | GENERIC_READ, 0, &fid, &oplock, NULL, | ||
181 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
182 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
183 | if (rc != 0) { | ||
184 | cERROR(1, ("Unable to open file to get ACL")); | ||
185 | FreeXid(xid); | ||
186 | return; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /* rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, pntsd, acllen, | ||
191 | ACL_TYPE_ACCESS); */ | ||
192 | |||
193 | if (unlock_file == TRUE) | ||
194 | atomic_dec(&open_file->wrtPending); | ||
195 | else | ||
196 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
197 | |||
198 | /* parse ACEs e.g. | ||
199 | rc = parse_sec_desc(pntsd, acllen, inode); | ||
200 | */ | ||
153 | 201 | ||
202 | FreeXid(xid); | ||
154 | return; | 203 | return; |
155 | } | 204 | } |
156 | 205 | ||
@@ -193,7 +242,8 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl) | |||
193 | 242 | ||
194 | 243 | ||
195 | static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | 244 | static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, |
196 | struct cifs_sid *pownersid, struct cifs_sid *pgrpsid) | 245 | struct cifs_sid *pownersid, struct cifs_sid *pgrpsid |
246 | struct inode *inode) | ||
197 | { | 247 | { |
198 | int i; | 248 | int i; |
199 | int num_aces = 0; | 249 | int num_aces = 0; |
@@ -281,7 +331,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | |||
281 | 331 | ||
282 | 332 | ||
283 | /* Convert CIFS ACL to POSIX form */ | 333 | /* Convert CIFS ACL to POSIX form */ |
284 | int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) | 334 | static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, |
335 | struct inode *inode) | ||
285 | { | 336 | { |
286 | int rc; | 337 | int rc; |
287 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | 338 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
@@ -310,14 +361,14 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) | |||
310 | if (rc) | 361 | if (rc) |
311 | return rc; | 362 | return rc; |
312 | 363 | ||
313 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr); | 364 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr, inode); |
314 | 365 | ||
315 | /* cifscred->uid = owner_sid_ptr->rid; | 366 | /* cifscred->uid = owner_sid_ptr->rid; |
316 | cifscred->gid = group_sid_ptr->rid; | 367 | cifscred->gid = group_sid_ptr->rid; |
317 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, | 368 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, |
318 | sizeof (struct cifs_sid)); | 369 | sizeof(struct cifs_sid)); |
319 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | 370 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, |
320 | sizeof (struct cifs_sid)); */ | 371 | sizeof(struct cifs_sid)); */ |
321 | 372 | ||
322 | 373 | ||
323 | return (0); | 374 | return (0); |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 7c445f8f233f..88c02ac97c3f 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -61,6 +61,9 @@ extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); | |||
61 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); | 61 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); |
62 | extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); | 62 | extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); |
63 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); | 63 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); |
64 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
65 | extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *); | ||
66 | #endif | ||
64 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); | 67 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); |
65 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | 68 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); |
66 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 69 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
@@ -92,7 +95,7 @@ extern int cifs_get_inode_info(struct inode **pinode, | |||
92 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 95 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
93 | const unsigned char *search_path, | 96 | const unsigned char *search_path, |
94 | struct super_block *sb, int xid); | 97 | struct super_block *sb, int xid); |
95 | extern void get_mode_from_acl(struct inode * inode, const char * search_path); | 98 | extern void acl_to_uid_mode(struct inode *inode, const char *search_path); |
96 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 99 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
97 | const char *); | 100 | const char *); |
98 | extern int cifs_umount(struct super_block *, struct cifs_sb_info *); | 101 | extern int cifs_umount(struct super_block *, struct cifs_sb_info *); |
@@ -311,7 +314,6 @@ extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, | |||
311 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 314 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
312 | extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); | 315 | extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); |
313 | #endif /* CIFS_WEAK_PW_HASH */ | 316 | #endif /* CIFS_WEAK_PW_HASH */ |
314 | extern int parse_sec_desc(struct cifs_ntsd *, int); | ||
315 | extern int CIFSSMBCopy(int xid, | 317 | extern int CIFSSMBCopy(int xid, |
316 | struct cifsTconInfo *source_tcon, | 318 | struct cifsTconInfo *source_tcon, |
317 | const char *fromName, | 319 | const char *fromName, |
@@ -336,8 +338,7 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, | |||
336 | const void *ea_value, const __u16 ea_value_len, | 338 | const void *ea_value, const __u16 ea_value_len, |
337 | const struct nls_table *nls_codepage, int remap_special_chars); | 339 | const struct nls_table *nls_codepage, int remap_special_chars); |
338 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, | 340 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, |
339 | __u16 fid, char *acl_inf, const int buflen, | 341 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); |
340 | const int acl_type /* ACCESS vs. DEFAULT */); | ||
341 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, | 342 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, |
342 | const unsigned char *searchName, | 343 | const unsigned char *searchName, |
343 | char *acl_inf, const int buflen, const int acl_type, | 344 | char *acl_inf, const int buflen, const int acl_type, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 61d24f6ee64e..cc17e98991f3 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -2526,12 +2526,15 @@ smb_init_ntransact(const __u16 sub_command, const int setup_count, | |||
2526 | 2526 | ||
2527 | static int | 2527 | static int |
2528 | validate_ntransact(char *buf, char **ppparm, char **ppdata, | 2528 | validate_ntransact(char *buf, char **ppparm, char **ppdata, |
2529 | int *pdatalen, int *pparmlen) | 2529 | __u32 *pdatalen, __u32 *pparmlen) |
2530 | { | 2530 | { |
2531 | char *end_of_smb; | 2531 | char *end_of_smb; |
2532 | __u32 data_count, data_offset, parm_count, parm_offset; | 2532 | __u32 data_count, data_offset, parm_count, parm_offset; |
2533 | struct smb_com_ntransact_rsp *pSMBr; | 2533 | struct smb_com_ntransact_rsp *pSMBr; |
2534 | 2534 | ||
2535 | *pdatalen = 0; | ||
2536 | *pparmlen = 0; | ||
2537 | |||
2535 | if (buf == NULL) | 2538 | if (buf == NULL) |
2536 | return -EINVAL; | 2539 | return -EINVAL; |
2537 | 2540 | ||
@@ -2568,6 +2571,8 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, | |||
2568 | cFYI(1, ("parm count and data count larger than SMB")); | 2571 | cFYI(1, ("parm count and data count larger than SMB")); |
2569 | return -EINVAL; | 2572 | return -EINVAL; |
2570 | } | 2573 | } |
2574 | *pdatalen = data_count; | ||
2575 | *pparmlen = parm_count; | ||
2571 | return 0; | 2576 | return 0; |
2572 | } | 2577 | } |
2573 | #endif /* CIFS_EXPERIMENTAL */ | 2578 | #endif /* CIFS_EXPERIMENTAL */ |
@@ -3069,8 +3074,7 @@ GetExtAttrOut: | |||
3069 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | 3074 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ |
3070 | int | 3075 | int |
3071 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | 3076 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, |
3072 | /* BB fix up return info */ char *acl_inf, const int buflen, | 3077 | struct cifs_ntsd **acl_inf, __u32 *pbuflen) |
3073 | const int acl_type) | ||
3074 | { | 3078 | { |
3075 | int rc = 0; | 3079 | int rc = 0; |
3076 | int buf_type = 0; | 3080 | int buf_type = 0; |
@@ -3079,6 +3083,9 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3079 | 3083 | ||
3080 | cFYI(1, ("GetCifsACL")); | 3084 | cFYI(1, ("GetCifsACL")); |
3081 | 3085 | ||
3086 | *pbuflen = 0; | ||
3087 | *acl_inf = NULL; | ||
3088 | |||
3082 | rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, | 3089 | rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, |
3083 | 8 /* parm len */, tcon, (void **) &pSMB); | 3090 | 8 /* parm len */, tcon, (void **) &pSMB); |
3084 | if (rc) | 3091 | if (rc) |
@@ -3101,34 +3108,52 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3101 | if (rc) { | 3108 | if (rc) { |
3102 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | 3109 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); |
3103 | } else { /* decode response */ | 3110 | } else { /* decode response */ |
3104 | struct cifs_ntsd *psec_desc; | ||
3105 | __le32 * parm; | 3111 | __le32 * parm; |
3106 | int parm_len; | 3112 | __u32 parm_len; |
3107 | int data_len; | 3113 | __u32 acl_len; |
3108 | int acl_len; | ||
3109 | struct smb_com_ntransact_rsp *pSMBr; | 3114 | struct smb_com_ntransact_rsp *pSMBr; |
3115 | char *pdata; | ||
3110 | 3116 | ||
3111 | /* validate_nttransact */ | 3117 | /* validate_nttransact */ |
3112 | rc = validate_ntransact(iov[0].iov_base, (char **)&parm, | 3118 | rc = validate_ntransact(iov[0].iov_base, (char **)&parm, |
3113 | (char **)&psec_desc, | 3119 | &pdata, &parm_len, pbuflen); |
3114 | &parm_len, &data_len); | ||
3115 | if (rc) | 3120 | if (rc) |
3116 | goto qsec_out; | 3121 | goto qsec_out; |
3117 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; | 3122 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; |
3118 | 3123 | ||
3119 | cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc)); | 3124 | cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, *acl_inf)); |
3120 | 3125 | ||
3121 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { | 3126 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { |
3122 | rc = -EIO; /* bad smb */ | 3127 | rc = -EIO; /* bad smb */ |
3128 | *pbuflen = 0; | ||
3123 | goto qsec_out; | 3129 | goto qsec_out; |
3124 | } | 3130 | } |
3125 | 3131 | ||
3126 | /* BB check that data area is minimum length and as big as acl_len */ | 3132 | /* BB check that data area is minimum length and as big as acl_len */ |
3127 | 3133 | ||
3128 | acl_len = le32_to_cpu(*parm); | 3134 | acl_len = le32_to_cpu(*parm); |
3129 | /* BB check if (acl_len > bufsize) */ | 3135 | if (acl_len != *pbuflen) { |
3136 | cERROR(1, ("acl length %d does not match %d", | ||
3137 | acl_len, *pbuflen)); | ||
3138 | if (*pbuflen > acl_len) | ||
3139 | *pbuflen = acl_len; | ||
3140 | } | ||
3130 | 3141 | ||
3131 | parse_sec_desc(psec_desc, acl_len); | 3142 | /* check if buffer is big enough for the acl |
3143 | header followed by the smallest SID */ | ||
3144 | if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) || | ||
3145 | (*pbuflen >= 64 * 1024)) { | ||
3146 | cERROR(1, ("bad acl length %d", *pbuflen)); | ||
3147 | rc = -EINVAL; | ||
3148 | *pbuflen = 0; | ||
3149 | } else { | ||
3150 | *acl_inf = kmalloc(*pbuflen, GFP_KERNEL); | ||
3151 | if (*acl_inf == NULL) { | ||
3152 | *pbuflen = 0; | ||
3153 | rc = -ENOMEM; | ||
3154 | } | ||
3155 | memcpy(*acl_inf, pdata, *pbuflen); | ||
3156 | } | ||
3132 | } | 3157 | } |
3133 | qsec_out: | 3158 | qsec_out: |
3134 | if (buf_type == CIFS_SMALL_BUFFER) | 3159 | if (buf_type == CIFS_SMALL_BUFFER) |
@@ -3383,7 +3408,7 @@ UnixQPathInfoRetry: | |||
3383 | memcpy((char *) pFindData, | 3408 | memcpy((char *) pFindData, |
3384 | (char *) &pSMBr->hdr.Protocol + | 3409 | (char *) &pSMBr->hdr.Protocol + |
3385 | data_offset, | 3410 | data_offset, |
3386 | sizeof (FILE_UNIX_BASIC_INFO)); | 3411 | sizeof(FILE_UNIX_BASIC_INFO)); |
3387 | } | 3412 | } |
3388 | } | 3413 | } |
3389 | cifs_buf_release(pSMB); | 3414 | cifs_buf_release(pSMB); |
@@ -3651,7 +3676,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, | |||
3651 | pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); | 3676 | pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); |
3652 | pSMB->SearchHandle = searchHandle; /* always kept as le */ | 3677 | pSMB->SearchHandle = searchHandle; /* always kept as le */ |
3653 | pSMB->SearchCount = | 3678 | pSMB->SearchCount = |
3654 | cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO)); | 3679 | cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); |
3655 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); | 3680 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); |
3656 | pSMB->ResumeKey = psrch_inf->resume_key; | 3681 | pSMB->ResumeKey = psrch_inf->resume_key; |
3657 | pSMB->SearchFlags = | 3682 | pSMB->SearchFlags = |
@@ -4333,7 +4358,7 @@ QFSDeviceRetry: | |||
4333 | } else { /* decode response */ | 4358 | } else { /* decode response */ |
4334 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | 4359 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); |
4335 | 4360 | ||
4336 | if (rc || (pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))) | 4361 | if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO))) |
4337 | rc = -EIO; /* bad smb */ | 4362 | rc = -EIO; /* bad smb */ |
4338 | else { | 4363 | else { |
4339 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 4364 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1e7e4c06d9e3..68ad4ca0cfa3 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1026,6 +1026,37 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
1026 | return total_written; | 1026 | return total_written; |
1027 | } | 1027 | } |
1028 | 1028 | ||
1029 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
1030 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode) | ||
1031 | { | ||
1032 | struct cifsFileInfo *open_file = NULL; | ||
1033 | |||
1034 | read_lock(&GlobalSMBSeslock); | ||
1035 | /* we could simply get the first_list_entry since write-only entries | ||
1036 | are always at the end of the list but since the first entry might | ||
1037 | have a close pending, we go through the whole list */ | ||
1038 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | ||
1039 | if (open_file->closePend) | ||
1040 | continue; | ||
1041 | if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) || | ||
1042 | (open_file->pfile->f_flags & O_RDONLY))) { | ||
1043 | if (!open_file->invalidHandle) { | ||
1044 | /* found a good file */ | ||
1045 | /* lock it so it will not be closed on us */ | ||
1046 | atomic_inc(&open_file->wrtPending); | ||
1047 | read_unlock(&GlobalSMBSeslock); | ||
1048 | return open_file; | ||
1049 | } /* else might as well continue, and look for | ||
1050 | another, or simply have the caller reopen it | ||
1051 | again rather than trying to fix this handle */ | ||
1052 | } else /* write only file */ | ||
1053 | break; /* write only files are last so must be done */ | ||
1054 | } | ||
1055 | read_unlock(&GlobalSMBSeslock); | ||
1056 | return NULL; | ||
1057 | } | ||
1058 | #endif | ||
1059 | |||
1029 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | 1060 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) |
1030 | { | 1061 | { |
1031 | struct cifsFileInfo *open_file; | 1062 | struct cifsFileInfo *open_file; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 9a5c0c925bab..9be0bbd20dfd 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -530,7 +530,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
530 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 530 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
531 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 531 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
532 | cFYI(1, ("Getting mode bits from ACL")); | 532 | cFYI(1, ("Getting mode bits from ACL")); |
533 | get_mode_from_acl(inode, search_path); | 533 | acl_to_uid_mode(inode, search_path); |
534 | } | 534 | } |
535 | #endif | 535 | #endif |
536 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 536 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c index e5c3e1212697..f13f96d42fcf 100644 --- a/fs/cifs/md5.c +++ b/fs/cifs/md5.c | |||
@@ -276,8 +276,8 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len, | |||
276 | } | 276 | } |
277 | 277 | ||
278 | /* start out by storing key in pads */ | 278 | /* start out by storing key in pads */ |
279 | memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad)); | 279 | memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); |
280 | memset(ctx->k_opad, 0, sizeof (ctx->k_opad)); | 280 | memset(ctx->k_opad, 0, sizeof(ctx->k_opad)); |
281 | memcpy(ctx->k_ipad, key, key_len); | 281 | memcpy(ctx->k_ipad, key, key_len); |
282 | memcpy(ctx->k_opad, key, key_len); | 282 | memcpy(ctx->k_opad, key, key_len); |
283 | 283 | ||
@@ -307,8 +307,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, | |||
307 | } | 307 | } |
308 | 308 | ||
309 | /* start out by storing key in pads */ | 309 | /* start out by storing key in pads */ |
310 | memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad)); | 310 | memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); |
311 | memset(ctx->k_opad, 0, sizeof (ctx->k_opad)); | 311 | memset(ctx->k_opad, 0, sizeof(ctx->k_opad)); |
312 | memcpy(ctx->k_ipad, key, key_len); | 312 | memcpy(ctx->k_ipad, key, key_len); |
313 | memcpy(ctx->k_opad, key, key_len); | 313 | memcpy(ctx->k_opad, key, key_len); |
314 | 314 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 51ec681fe74a..15546c2354c5 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -73,7 +73,7 @@ sesInfoAlloc(void) | |||
73 | { | 73 | { |
74 | struct cifsSesInfo *ret_buf; | 74 | struct cifsSesInfo *ret_buf; |
75 | 75 | ||
76 | ret_buf = kzalloc(sizeof (struct cifsSesInfo), GFP_KERNEL); | 76 | ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL); |
77 | if (ret_buf) { | 77 | if (ret_buf) { |
78 | write_lock(&GlobalSMBSeslock); | 78 | write_lock(&GlobalSMBSeslock); |
79 | atomic_inc(&sesInfoAllocCount); | 79 | atomic_inc(&sesInfoAllocCount); |
@@ -109,7 +109,7 @@ struct cifsTconInfo * | |||
109 | tconInfoAlloc(void) | 109 | tconInfoAlloc(void) |
110 | { | 110 | { |
111 | struct cifsTconInfo *ret_buf; | 111 | struct cifsTconInfo *ret_buf; |
112 | ret_buf = kzalloc(sizeof (struct cifsTconInfo), GFP_KERNEL); | 112 | ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL); |
113 | if (ret_buf) { | 113 | if (ret_buf) { |
114 | write_lock(&GlobalSMBSeslock); | 114 | write_lock(&GlobalSMBSeslock); |
115 | atomic_inc(&tconInfoAllocCount); | 115 | atomic_inc(&tconInfoAllocCount); |
@@ -298,7 +298,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
298 | memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ | 298 | memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ |
299 | 299 | ||
300 | buffer->smb_buf_length = | 300 | buffer->smb_buf_length = |
301 | (2 * word_count) + sizeof (struct smb_hdr) - | 301 | (2 * word_count) + sizeof(struct smb_hdr) - |
302 | 4 /* RFC 1001 length field does not count */ + | 302 | 4 /* RFC 1001 length field does not count */ + |
303 | 2 /* for bcc field itself */ ; | 303 | 2 /* for bcc field itself */ ; |
304 | /* Note that this is the only network field that has to be converted | 304 | /* Note that this is the only network field that has to be converted |
@@ -422,8 +422,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) | |||
422 | __u32 clc_len; /* calculated length */ | 422 | __u32 clc_len; /* calculated length */ |
423 | cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); | 423 | cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); |
424 | 424 | ||
425 | if (length < 2 + sizeof (struct smb_hdr)) { | 425 | if (length < 2 + sizeof(struct smb_hdr)) { |
426 | if ((length >= sizeof (struct smb_hdr) - 1) | 426 | if ((length >= sizeof(struct smb_hdr) - 1) |
427 | && (smb->Status.CifsError != 0)) { | 427 | && (smb->Status.CifsError != 0)) { |
428 | smb->WordCount = 0; | 428 | smb->WordCount = 0; |
429 | /* some error cases do not return wct and bcc */ | 429 | /* some error cases do not return wct and bcc */ |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index f06359cb22ee..4d35c034755a 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -793,8 +793,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
793 | if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */ | 793 | if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */ |
794 | for (i = 0; | 794 | for (i = 0; |
795 | i < | 795 | i < |
796 | sizeof (mapping_table_ERRDOS) / | 796 | sizeof(mapping_table_ERRDOS) / |
797 | sizeof (struct smb_to_posix_error); i++) { | 797 | sizeof(struct smb_to_posix_error); i++) { |
798 | if (mapping_table_ERRDOS[i].smb_err == 0) | 798 | if (mapping_table_ERRDOS[i].smb_err == 0) |
799 | break; | 799 | break; |
800 | else if (mapping_table_ERRDOS[i].smb_err == | 800 | else if (mapping_table_ERRDOS[i].smb_err == |
@@ -807,8 +807,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
807 | } else if (smberrclass == ERRSRV) { /* server class of error codes */ | 807 | } else if (smberrclass == ERRSRV) { /* server class of error codes */ |
808 | for (i = 0; | 808 | for (i = 0; |
809 | i < | 809 | i < |
810 | sizeof (mapping_table_ERRSRV) / | 810 | sizeof(mapping_table_ERRSRV) / |
811 | sizeof (struct smb_to_posix_error); i++) { | 811 | sizeof(struct smb_to_posix_error); i++) { |
812 | if (mapping_table_ERRSRV[i].smb_err == 0) | 812 | if (mapping_table_ERRSRV[i].smb_err == 0) |
813 | break; | 813 | break; |
814 | else if (mapping_table_ERRSRV[i].smb_err == | 814 | else if (mapping_table_ERRSRV[i].smb_err == |
@@ -837,14 +837,14 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
837 | unsigned int | 837 | unsigned int |
838 | smbCalcSize(struct smb_hdr *ptr) | 838 | smbCalcSize(struct smb_hdr *ptr) |
839 | { | 839 | { |
840 | return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + | 840 | return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + |
841 | 2 /* size of the bcc field */ + BCC(ptr)); | 841 | 2 /* size of the bcc field */ + BCC(ptr)); |
842 | } | 842 | } |
843 | 843 | ||
844 | unsigned int | 844 | unsigned int |
845 | smbCalcSize_LE(struct smb_hdr *ptr) | 845 | smbCalcSize_LE(struct smb_hdr *ptr) |
846 | { | 846 | { |
847 | return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + | 847 | return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + |
848 | 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr))); | 848 | 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr))); |
849 | } | 849 | } |
850 | 850 | ||
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 90542a39be17..bd3c4674f2ba 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -135,7 +135,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) | |||
135 | 135 | ||
136 | wpwd[len] = 0; /* Ensure string is null terminated */ | 136 | wpwd[len] = 0; /* Ensure string is null terminated */ |
137 | /* Calculate length in bytes */ | 137 | /* Calculate length in bytes */ |
138 | len = _my_wcslen(wpwd) * sizeof (__u16); | 138 | len = _my_wcslen(wpwd) * sizeof(__u16); |
139 | 139 | ||
140 | mdfour(p16, (unsigned char *) wpwd, len); | 140 | mdfour(p16, (unsigned char *) wpwd, len); |
141 | memset(wpwd, 0, 129 * 2); | 141 | memset(wpwd, 0, 129 * 2); |
@@ -167,7 +167,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) | |||
167 | E_P16((unsigned char *) passwd, (unsigned char *) p16); | 167 | E_P16((unsigned char *) passwd, (unsigned char *) p16); |
168 | 168 | ||
169 | /* clear out local copy of user's password (just being paranoid). */ | 169 | /* clear out local copy of user's password (just being paranoid). */ |
170 | memset(passwd, '\0', sizeof (passwd)); | 170 | memset(passwd, '\0', sizeof(passwd)); |
171 | } | 171 | } |
172 | #endif | 172 | #endif |
173 | 173 | ||
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 369e838bebd3..12b125ff0bd0 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -265,6 +265,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
265 | else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 265 | else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
266 | __u16 fid; | 266 | __u16 fid; |
267 | int oplock = FALSE; | 267 | int oplock = FALSE; |
268 | struct cifs_ntsd *pacl = NULL; | ||
269 | __u32 buflen = 0; | ||
268 | if (experimEnabled) | 270 | if (experimEnabled) |
269 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 271 | rc = CIFSSMBOpen(xid, pTcon, full_path, |
270 | FILE_OPEN, GENERIC_READ, 0, &fid, | 272 | FILE_OPEN, GENERIC_READ, 0, &fid, |
@@ -274,9 +276,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
274 | /* else rc is EOPNOTSUPP from above */ | 276 | /* else rc is EOPNOTSUPP from above */ |
275 | 277 | ||
276 | if(rc == 0) { | 278 | if(rc == 0) { |
277 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, | 279 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl, |
278 | ea_value, buf_size, | 280 | &buflen); |
279 | ACL_TYPE_ACCESS); | ||
280 | CIFSSMBClose(xid, pTcon, fid); | 281 | CIFSSMBClose(xid, pTcon, fid); |
281 | } | 282 | } |
282 | } | 283 | } |