acl.c (37bc15392a2363ca822b2c2828e0ccafbea32f75) | acl.c (64e178a7118b1cf7648391755e44dcc209091003) |
---|---|
1/* 2 * linux/fs/ext2/acl.c 3 * 4 * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de> 5 */ 6 7#include <linux/capability.h> 8#include <linux/init.h> --- 134 unchanged lines hidden (view full) --- 143struct posix_acl * 144ext2_get_acl(struct inode *inode, int type) 145{ 146 int name_index; 147 char *value = NULL; 148 struct posix_acl *acl; 149 int retval; 150 | 1/* 2 * linux/fs/ext2/acl.c 3 * 4 * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de> 5 */ 6 7#include <linux/capability.h> 8#include <linux/init.h> --- 134 unchanged lines hidden (view full) --- 143struct posix_acl * 144ext2_get_acl(struct inode *inode, int type) 145{ 146 int name_index; 147 char *value = NULL; 148 struct posix_acl *acl; 149 int retval; 150 |
151 if (!test_opt(inode->i_sb, POSIX_ACL)) 152 return NULL; 153 154 acl = get_cached_acl(inode, type); 155 if (acl != ACL_NOT_CACHED) 156 return acl; 157 | |
158 switch (type) { 159 case ACL_TYPE_ACCESS: 160 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 161 break; 162 case ACL_TYPE_DEFAULT: 163 name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; 164 break; 165 default: --- 18 unchanged lines hidden (view full) --- 184 set_cached_acl(inode, type, acl); 185 186 return acl; 187} 188 189/* 190 * inode->i_mutex: down 191 */ | 151 switch (type) { 152 case ACL_TYPE_ACCESS: 153 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 154 break; 155 case ACL_TYPE_DEFAULT: 156 name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; 157 break; 158 default: --- 18 unchanged lines hidden (view full) --- 177 set_cached_acl(inode, type, acl); 178 179 return acl; 180} 181 182/* 183 * inode->i_mutex: down 184 */ |
192static int 193ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 185int 186ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
194{ 195 int name_index; 196 void *value = NULL; 197 size_t size = 0; 198 int error; 199 | 187{ 188 int name_index; 189 void *value = NULL; 190 size_t size = 0; 191 int error; 192 |
200 if (S_ISLNK(inode->i_mode)) 201 return -EOPNOTSUPP; 202 if (!test_opt(inode->i_sb, POSIX_ACL)) 203 return 0; 204 | |
205 switch(type) { 206 case ACL_TYPE_ACCESS: 207 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 208 if (acl) { 209 error = posix_acl_equiv_mode(acl, &inode->i_mode); 210 if (error < 0) 211 return error; 212 else { --- 32 unchanged lines hidden (view full) --- 245 * Initialize the ACLs of a new inode. Called from ext2_new_inode. 246 * 247 * dir->i_mutex: down 248 * inode->i_mutex: up (access to inode is still exclusive) 249 */ 250int 251ext2_init_acl(struct inode *inode, struct inode *dir) 252{ | 193 switch(type) { 194 case ACL_TYPE_ACCESS: 195 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 196 if (acl) { 197 error = posix_acl_equiv_mode(acl, &inode->i_mode); 198 if (error < 0) 199 return error; 200 else { --- 32 unchanged lines hidden (view full) --- 233 * Initialize the ACLs of a new inode. Called from ext2_new_inode. 234 * 235 * dir->i_mutex: down 236 * inode->i_mutex: up (access to inode is still exclusive) 237 */ 238int 239ext2_init_acl(struct inode *inode, struct inode *dir) 240{ |
253 struct posix_acl *acl = NULL; 254 int error = 0; | 241 struct posix_acl *default_acl, *acl; 242 int error; |
255 | 243 |
256 if (!S_ISLNK(inode->i_mode)) { 257 if (test_opt(dir->i_sb, POSIX_ACL)) { 258 acl = ext2_get_acl(dir, ACL_TYPE_DEFAULT); 259 if (IS_ERR(acl)) 260 return PTR_ERR(acl); 261 } 262 if (!acl) 263 inode->i_mode &= ~current_umask(); 264 } 265 if (test_opt(inode->i_sb, POSIX_ACL) && acl) { 266 if (S_ISDIR(inode->i_mode)) { 267 error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl); 268 if (error) 269 goto cleanup; 270 } 271 error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); 272 if (error < 0) 273 return error; 274 if (error > 0) { 275 /* This is an extended ACL */ 276 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); 277 } 278 } 279cleanup: 280 posix_acl_release(acl); 281 return error; 282} 283 284/* 285 * Does chmod for an inode that may have an Access Control List. The 286 * inode->i_mode field must be updated to the desired value by the caller 287 * before calling this function. 288 * Returns 0 on success, or a negative error number. 289 * 290 * We change the ACL rather than storing some ACL entries in the file 291 * mode permission bits (which would be more efficient), because that 292 * would break once additional permissions (like ACL_APPEND, ACL_DELETE 293 * for directories) are added. There are no more bits available in the 294 * file mode. 295 * 296 * inode->i_mutex: down 297 */ 298int 299ext2_acl_chmod(struct inode *inode) 300{ 301 struct posix_acl *acl; 302 int error; 303 304 if (!test_opt(inode->i_sb, POSIX_ACL)) 305 return 0; 306 if (S_ISLNK(inode->i_mode)) 307 return -EOPNOTSUPP; 308 acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); 309 if (IS_ERR(acl) || !acl) 310 return PTR_ERR(acl); 311 error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); | 244 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); |
312 if (error) 313 return error; | 245 if (error) 246 return error; |
314 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); 315 posix_acl_release(acl); 316 return error; 317} | |
318 | 247 |
319/* 320 * Extended attribut handlers 321 */ 322static size_t 323ext2_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_size, 324 const char *name, size_t name_len, int type) 325{ 326 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); 327 328 if (!test_opt(dentry->d_sb, POSIX_ACL)) 329 return 0; 330 if (list && size <= list_size) 331 memcpy(list, POSIX_ACL_XATTR_ACCESS, size); 332 return size; 333} 334 335static size_t 336ext2_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_size, 337 const char *name, size_t name_len, int type) 338{ 339 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); 340 341 if (!test_opt(dentry->d_sb, POSIX_ACL)) 342 return 0; 343 if (list && size <= list_size) 344 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); 345 return size; 346} 347 348static int 349ext2_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, 350 size_t size, int type) 351{ 352 struct posix_acl *acl; 353 int error; 354 355 if (strcmp(name, "") != 0) 356 return -EINVAL; 357 if (!test_opt(dentry->d_sb, POSIX_ACL)) 358 return -EOPNOTSUPP; 359 360 acl = ext2_get_acl(dentry->d_inode, type); 361 if (IS_ERR(acl)) 362 return PTR_ERR(acl); 363 if (acl == NULL) 364 return -ENODATA; 365 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); 366 posix_acl_release(acl); 367 | 248 if (default_acl) { 249 error = ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); 250 posix_acl_release(default_acl); 251 } 252 if (acl) { 253 if (!error) 254 error = ext2_set_acl(inode, acl, ACL_TYPE_ACCESS); 255 posix_acl_release(acl); 256 } |
368 return error; 369} | 257 return error; 258} |
370 371static int 372ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, 373 size_t size, int flags, int type) 374{ 375 struct posix_acl *acl; 376 int error; 377 378 if (strcmp(name, "") != 0) 379 return -EINVAL; 380 if (!test_opt(dentry->d_sb, POSIX_ACL)) 381 return -EOPNOTSUPP; 382 if (!inode_owner_or_capable(dentry->d_inode)) 383 return -EPERM; 384 385 if (value) { 386 acl = posix_acl_from_xattr(&init_user_ns, value, size); 387 if (IS_ERR(acl)) 388 return PTR_ERR(acl); 389 else if (acl) { 390 error = posix_acl_valid(acl); 391 if (error) 392 goto release_and_out; 393 } 394 } else 395 acl = NULL; 396 397 error = ext2_set_acl(dentry->d_inode, type, acl); 398 399release_and_out: 400 posix_acl_release(acl); 401 return error; 402} 403 404const struct xattr_handler ext2_xattr_acl_access_handler = { 405 .prefix = POSIX_ACL_XATTR_ACCESS, 406 .flags = ACL_TYPE_ACCESS, 407 .list = ext2_xattr_list_acl_access, 408 .get = ext2_xattr_get_acl, 409 .set = ext2_xattr_set_acl, 410}; 411 412const struct xattr_handler ext2_xattr_acl_default_handler = { 413 .prefix = POSIX_ACL_XATTR_DEFAULT, 414 .flags = ACL_TYPE_DEFAULT, 415 .list = ext2_xattr_list_acl_default, 416 .get = ext2_xattr_get_acl, 417 .set = ext2_xattr_set_acl, 418}; | |