X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_permission.c;h=6a136bafa062b2efc9bd924f3d689052f1661413;hb=83ddd179225821e5c2aee1adb72dab26150ab385;hp=282d5308225023377eee829522b0dd3f07168c3d;hpb=d10200a80770f0029d1d665af954187b9ad883df;p=fs%2Flustre-release.git diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index 282d530..6a136ba 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -23,11 +23,10 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2016, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. * * lustre/mdd/mdd_permission.c * @@ -40,13 +39,12 @@ #define DEBUG_SUBSYSTEM S_MDS #include -#include #include #include #include #include "mdd_internal.h" -#ifdef CONFIG_FS_POSIX_ACL +#ifdef CONFIG_LUSTRE_FS_POSIX_ACL /* * Hold write_lock for o. @@ -54,7 +52,7 @@ int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode, struct thandle *handle) { - struct lu_buf *buf; + struct lu_buf buf; posix_acl_xattr_header *head; posix_acl_xattr_entry *entry; int entry_count; @@ -62,19 +60,27 @@ int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode, ENTRY; - buf = mdd_buf_get(env, mdd_env_info(env)->mti_xattr_buf, - sizeof(mdd_env_info(env)->mti_xattr_buf)); + lu_buf_check_and_alloc(&mdd_env_info(env)->mti_xattr_buf, + min_t(unsigned int, + mdd_obj2mdd_dev(o)->mdd_dt_conf.ddp_max_ea_size, + XATTR_SIZE_MAX)); + buf = mdd_env_info(env)->mti_xattr_buf; + if (buf.lb_buf == NULL) + RETURN(-ENOMEM); - rc = mdo_xattr_get(env, o, buf, XATTR_NAME_ACL_ACCESS); + if (buf.lb_len > XATTR_SIZE_MAX) + buf.lb_len = XATTR_SIZE_MAX; + + rc = mdo_xattr_get(env, o, &buf, XATTR_NAME_ACL_ACCESS); if ((rc == -EOPNOTSUPP) || (rc == -ENODATA)) RETURN(0); else if (rc <= 0) RETURN(rc); - buf->lb_len = rc; - head = (posix_acl_xattr_header *)(buf->lb_buf); - entry = head->a_entries; - entry_count = (buf->lb_len - sizeof(head->a_version)) / + buf.lb_len = rc; + head = (posix_acl_xattr_header *)(buf.lb_buf); + entry = GET_POSIX_ACL_XATTR_ENTRY(head); + entry_count = (buf.lb_len - sizeof(head->a_version)) / sizeof(posix_acl_xattr_entry); if (entry_count <= 0) RETURN(0); @@ -83,7 +89,7 @@ int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode, if (rc) RETURN(rc); - rc = mdo_xattr_set(env, o, buf, XATTR_NAME_ACL_ACCESS, + rc = mdo_xattr_set(env, o, &buf, XATTR_NAME_ACL_ACCESS, 0, handle); RETURN(rc); } @@ -102,7 +108,7 @@ int mdd_acl_set(const struct lu_env *env, struct mdd_object *obj, ENTRY; head = (posix_acl_xattr_header *)(buf->lb_buf); - entry = head->a_entries; + entry = GET_POSIX_ACL_XATTR_ENTRY(head); entry_count = (buf->lb_len - sizeof(head->a_version)) / sizeof(posix_acl_xattr_entry); if (entry_count <= 0) @@ -141,7 +147,7 @@ int mdd_acl_set(const struct lu_env *env, struct mdd_object *obj, if (rc) GOTO(stop, rc); - mdd_write_lock(env, obj, MOR_TGT_CHILD); + mdd_write_lock(env, obj, DT_TGT_CHILD); /* whether ACL can be represented by i_mode only */ if (not_equiv) rc = mdo_xattr_set(env, obj, buf, XATTR_NAME_ACL_ACCESS, fl, @@ -182,7 +188,7 @@ int __mdd_fix_mode_acl(const struct lu_env *env, struct lu_buf *buf, ENTRY; head = (posix_acl_xattr_header *)(buf->lb_buf); - entry = head->a_entries; + entry = GET_POSIX_ACL_XATTR_ENTRY(head); entry_count = (buf->lb_len - sizeof(head->a_version)) / sizeof(posix_acl_xattr_entry); if (entry_count <= 0) @@ -199,34 +205,43 @@ int __mdd_fix_mode_acl(const struct lu_env *env, struct lu_buf *buf, * Hold read_lock for obj. */ static int mdd_check_acl(const struct lu_env *env, struct mdd_object *obj, - const struct lu_attr *la, int mask) + const struct lu_attr *la, unsigned int may_mask) { -#ifdef CONFIG_FS_POSIX_ACL +#ifdef CONFIG_LUSTRE_FS_POSIX_ACL struct lu_ucred *uc = lu_ucred_assert(env); posix_acl_xattr_header *head; posix_acl_xattr_entry *entry; - struct lu_buf *buf; + struct lu_buf buf; int entry_count; int rc; ENTRY; - buf = mdd_buf_get(env, mdd_env_info(env)->mti_xattr_buf, - sizeof(mdd_env_info(env)->mti_xattr_buf)); - rc = mdo_xattr_get(env, obj, buf, XATTR_NAME_ACL_ACCESS); + lu_buf_check_and_alloc(&mdd_env_info(env)->mti_xattr_buf, + min_t(unsigned int, + mdd_obj2mdd_dev(obj)->mdd_dt_conf.ddp_max_ea_size, + XATTR_SIZE_MAX)); + buf = mdd_env_info(env)->mti_xattr_buf; + if (buf.lb_buf == NULL) + RETURN(-ENOMEM); + + if (buf.lb_len > XATTR_SIZE_MAX) + buf.lb_len = XATTR_SIZE_MAX; + + rc = mdo_xattr_get(env, obj, &buf, XATTR_NAME_ACL_ACCESS); if (rc <= 0) RETURN(rc ? : -EACCES); - buf->lb_len = rc; - head = (posix_acl_xattr_header *)(buf->lb_buf); - entry = head->a_entries; - entry_count = posix_acl_xattr_count(buf->lb_len); + buf.lb_len = rc; + head = (posix_acl_xattr_header *)(buf.lb_buf); + entry = GET_POSIX_ACL_XATTR_ENTRY(head); + entry_count = posix_acl_xattr_count(buf.lb_len); /* Disregard empty ACLs and fall back to * standard UNIX permissions. See LU-5434 */ if (entry_count <= 0) RETURN(-EAGAIN); - rc = lustre_posix_acl_permission(uc, la, mask, entry, entry_count); + rc = lustre_posix_acl_permission(uc, la, may_mask, entry, entry_count); RETURN(rc); #else ENTRY; @@ -235,14 +250,15 @@ static int mdd_check_acl(const struct lu_env *env, struct mdd_object *obj, } int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj, - const struct lu_attr *la, int mask, int role) + const struct lu_attr *la, unsigned int may_mask, + int role) { struct lu_ucred *uc = lu_ucred(env); __u32 mode; int rc; ENTRY; - if (mask == 0) + if (may_mask == 0) RETURN(0); /* These means unnecessary for permission check */ @@ -256,7 +272,8 @@ int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj, /* * Nobody gets write access to an immutable file. */ - if (mask & MAY_WRITE && la->la_flags & LUSTRE_IMMUTABLE_FL) + if ((may_mask & MAY_WRITE) && (la->la_valid & LA_FLAGS) && + (la->la_flags & LUSTRE_IMMUTABLE_FL)) RETURN(-EACCES); LASSERT(la != NULL); @@ -264,35 +281,35 @@ int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj, mode = la->la_mode; if (uc->uc_fsuid == la->la_uid) { mode >>= 6; - } else { - if (mode & S_IRWXG) { - if (role != -1) - mdd_read_lock(env, obj, role); - rc = mdd_check_acl(env, obj, la, mask); - if (role != -1) - mdd_read_unlock(env, obj); - if (rc == -EACCES) - goto check_capabilities; - else if ((rc != -EAGAIN) && (rc != -EOPNOTSUPP) && - (rc != -ENODATA)) - RETURN(rc); - } - if (lustre_in_group_p(uc, la->la_gid)) - mode >>= 3; - } - - if (((mode & mask & S_IRWXO) == mask)) - RETURN(0); + } else { + if (mode & S_IRWXG) { + if (role != -1) + mdd_read_lock(env, obj, role); + rc = mdd_check_acl(env, obj, la, may_mask); + if (role != -1) + mdd_read_unlock(env, obj); + if (rc == -EACCES) + goto check_capabilities; + else if ((rc != -EAGAIN) && (rc != -EOPNOTSUPP) && + (rc != -ENODATA)) + RETURN(rc); + } + if (lustre_in_group_p(uc, la->la_gid)) + mode >>= 3; + } + + if (((mode & may_mask & S_IRWXO) == may_mask)) + RETURN(0); check_capabilities: - if (!(mask & MAY_EXEC) || + if (!(may_mask & MAY_EXEC) || (la->la_mode & S_IXUGO) || S_ISDIR(la->la_mode)) - if (md_capable(uc, CFS_CAP_DAC_OVERRIDE)) + if (md_capable(uc, CAP_DAC_OVERRIDE)) RETURN(0); - if ((mask == MAY_READ) || - (S_ISDIR(la->la_mode) && !(mask & MAY_WRITE))) - if (md_capable(uc, CFS_CAP_DAC_READ_SEARCH)) + if ((may_mask == MAY_READ) || + (S_ISDIR(la->la_mode) && !(may_mask & MAY_WRITE))) + if (md_capable(uc, CAP_DAC_READ_SEARCH)) RETURN(0); CDEBUG(D_SEC, "permission denied, mode %x, fsuid %u, uid %u\n", @@ -301,9 +318,9 @@ check_capabilities: RETURN(-EACCES); } -int mdd_permission(const struct lu_env *env, - struct md_object *pobj, struct md_object *cobj, - struct md_attr *ma, int mask) +int mdd_permission(const struct lu_env *env, struct md_object *pobj, + struct md_object *cobj, struct md_attr *ma, + unsigned int may_mask) { struct mdd_object *mdd_pobj = NULL; struct mdd_object *mdd_cobj; @@ -327,22 +344,16 @@ int mdd_permission(const struct lu_env *env, if (rc) RETURN(rc); - /* For cross_open case, the "mask" is open flags, - * so convert it to permission mask first. - * XXX: MDS_OPEN_CROSS must be NOT equal to permission mask MAY_*. */ - if (unlikely(mask & MDS_OPEN_CROSS)) - mask = accmode(env, cattr, mask & ~MDS_OPEN_CROSS); - rc = mdd_permission_internal_locked(env, mdd_cobj, cattr, - mask & ~MAY_RGETFACL, - MOR_TGT_CHILD); + may_mask & ~MAY_RGETFACL, + DT_TGT_CHILD); - if (unlikely(rc == 0 && (mask & MAY_RGETFACL))) { + if (unlikely(rc == 0 && (may_mask & MAY_RGETFACL))) { if (likely(!uc)) uc = lu_ucred_assert(env); if (cattr->la_uid != uc->uc_fsuid && - !md_capable(uc, CFS_CAP_FOWNER)) + !md_capable(uc, CAP_FOWNER)) rc = -EPERM; }