diff options
Diffstat (limited to 'fs/cifs/cifsacl.c')
-rw-r--r-- | fs/cifs/cifsacl.c | 133 |
1 files changed, 70 insertions, 63 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 3a2d67b182d4..cad2da3a447d 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -155,69 +155,11 @@ static void access_flags_to_mode(__u32 ace_flags, umode_t *pmode, | |||
155 | *pmode |= (S_IXUGO & bits_to_set); | 155 | *pmode |= (S_IXUGO & bits_to_set); |
156 | 156 | ||
157 | #ifdef CONFIG_CIFS_DEBUG2 | 157 | #ifdef CONFIG_CIFS_DEBUG2 |
158 | cFYI(1, ("access flags 0x%x mode now 0x%x", ace_flags, *pmode); | 158 | cFYI(1, ("access flags 0x%x mode now 0x%x", ace_flags, *pmode)); |
159 | #endif | 159 | #endif |
160 | return; | 160 | return; |
161 | } | 161 | } |
162 | 162 | ||
163 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | ||
164 | |||
165 | void acl_to_uid_mode(struct inode *inode, const char *path) | ||
166 | { | ||
167 | struct cifsFileInfo *open_file; | ||
168 | int unlock_file = FALSE; | ||
169 | int xid; | ||
170 | int rc = -EIO; | ||
171 | __u16 fid; | ||
172 | struct super_block *sb; | ||
173 | struct cifs_sb_info *cifs_sb; | ||
174 | |||
175 | cFYI(1, ("get mode from ACL for %s", path)); | ||
176 | |||
177 | if (inode == NULL) | ||
178 | return; | ||
179 | |||
180 | xid = GetXid(); | ||
181 | open_file = find_readable_file(CIFS_I(inode)); | ||
182 | if (open_file) { | ||
183 | unlock_file = TRUE; | ||
184 | fid = open_file->netfid; | ||
185 | } else { | ||
186 | int oplock = FALSE; | ||
187 | /* open file */ | ||
188 | sb = inode->i_sb; | ||
189 | if (sb == NULL) { | ||
190 | FreeXid(xid); | ||
191 | return; | ||
192 | } | ||
193 | cifs_sb = CIFS_SB(sb); | ||
194 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
195 | GENERIC_READ, 0, &fid, &oplock, NULL, | ||
196 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
197 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
198 | if (rc != 0) { | ||
199 | cERROR(1, ("Unable to open file to get ACL")); | ||
200 | FreeXid(xid); | ||
201 | return; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | /* rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, pntsd, acllen, | ||
206 | ACL_TYPE_ACCESS); */ | ||
207 | |||
208 | if (unlock_file == TRUE) | ||
209 | atomic_dec(&open_file->wrtPending); | ||
210 | else | ||
211 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
212 | |||
213 | /* parse ACEs e.g. | ||
214 | rc = parse_sec_desc(pntsd, acllen, inode); | ||
215 | */ | ||
216 | |||
217 | FreeXid(xid); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | 163 | ||
222 | static void parse_ace(struct cifs_ace *pace, char *end_of_acl) | 164 | static void parse_ace(struct cifs_ace *pace, char *end_of_acl) |
223 | { | 165 | { |
@@ -314,12 +256,12 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
314 | 256 | ||
315 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | 257 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) |
316 | { | 258 | { |
317 | |||
318 | /* BB need to add parm so we can store the SID BB */ | 259 | /* BB need to add parm so we can store the SID BB */ |
319 | 260 | ||
320 | /* validate that we do not go past end of acl */ | 261 | /* validate that we do not go past end of ACL - sid must be at least 8 |
321 | if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { | 262 | bytes long (assuming no sub-auths - e.g. the null SID */ |
322 | cERROR(1, ("ACL too small to parse SID")); | 263 | if (end_of_acl < (char *)psid + 8) { |
264 | cERROR(1, ("ACL too small to parse SID %p", psid)); | ||
323 | return -EINVAL; | 265 | return -EINVAL; |
324 | } | 266 | } |
325 | 267 | ||
@@ -354,6 +296,9 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | |||
354 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ | 296 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ |
355 | char *end_of_acl = ((char *)pntsd) + acl_len; | 297 | char *end_of_acl = ((char *)pntsd) + acl_len; |
356 | 298 | ||
299 | if ((inode == NULL) || (pntsd == NULL)) | ||
300 | return -EIO; | ||
301 | |||
357 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | 302 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
358 | le32_to_cpu(pntsd->osidoffset)); | 303 | le32_to_cpu(pntsd->osidoffset)); |
359 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | 304 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
@@ -368,6 +313,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | |||
368 | le32_to_cpu(pntsd->sacloffset), | 313 | le32_to_cpu(pntsd->sacloffset), |
369 | le32_to_cpu(pntsd->dacloffset))); | 314 | le32_to_cpu(pntsd->dacloffset))); |
370 | #endif | 315 | #endif |
316 | /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ | ||
371 | rc = parse_sid(owner_sid_ptr, end_of_acl); | 317 | rc = parse_sid(owner_sid_ptr, end_of_acl); |
372 | if (rc) | 318 | if (rc) |
373 | return rc; | 319 | return rc; |
@@ -388,4 +334,65 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | |||
388 | 334 | ||
389 | return (0); | 335 | return (0); |
390 | } | 336 | } |
337 | |||
338 | |||
339 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | ||
340 | |||
341 | void acl_to_uid_mode(struct inode *inode, const char *path) | ||
342 | { | ||
343 | struct cifsFileInfo *open_file; | ||
344 | int unlock_file = FALSE; | ||
345 | int xid; | ||
346 | int rc = -EIO; | ||
347 | __u16 fid; | ||
348 | struct super_block *sb; | ||
349 | struct cifs_sb_info *cifs_sb; | ||
350 | struct cifs_ntsd *pntsd = NULL; | ||
351 | __u32 acllen; | ||
352 | |||
353 | cFYI(1, ("get mode from ACL for %s", path)); | ||
354 | |||
355 | if (inode == NULL) | ||
356 | return; | ||
357 | |||
358 | xid = GetXid(); | ||
359 | open_file = find_readable_file(CIFS_I(inode)); | ||
360 | sb = inode->i_sb; | ||
361 | if (sb == NULL) { | ||
362 | FreeXid(xid); | ||
363 | return; | ||
364 | } | ||
365 | cifs_sb = CIFS_SB(sb); | ||
366 | |||
367 | if (open_file) { | ||
368 | unlock_file = TRUE; | ||
369 | fid = open_file->netfid; | ||
370 | } else { | ||
371 | int oplock = FALSE; | ||
372 | /* open file */ | ||
373 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
374 | GENERIC_READ, 0, &fid, &oplock, NULL, | ||
375 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
376 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
377 | if (rc != 0) { | ||
378 | cERROR(1, ("Unable to open file to get ACL")); | ||
379 | FreeXid(xid); | ||
380 | return; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, &acllen); | ||
385 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, acllen)); | ||
386 | if (unlock_file == TRUE) | ||
387 | atomic_dec(&open_file->wrtPending); | ||
388 | else | ||
389 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
390 | |||
391 | /* parse ACEs */ | ||
392 | if (!rc) | ||
393 | rc = parse_sec_desc(pntsd, acllen, inode); | ||
394 | kfree(pntsd); | ||
395 | FreeXid(xid); | ||
396 | return; | ||
397 | } | ||
391 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 398 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |