X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_permission.c;h=01b30e1dd21b2c34d21d71618d7c73725807b394;hb=1db90b29ad676c2cf1888ef5a7c623161ff23bf9;hp=f137d41e16a1b51ccc7ef097ebe593894a8a16b8;hpb=b6a3222a0b35b939f40bb93087d8993e81885b26;p=fs%2Flustre-release.git diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index f137d41..01b30e1 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -44,7 +40,6 @@ #define DEBUG_SUBSYSTEM S_MDS #include -#include #include #include #include @@ -58,7 +53,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; @@ -66,19 +61,26 @@ 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(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); + + if (buf.lb_len > XATTR_SIZE_MAX) + buf.lb_len = XATTR_SIZE_MAX; - rc = mdo_xattr_get(env, o, buf, XATTR_NAME_ACL_ACCESS, BYPASS_CAPA); + 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); @@ -87,8 +89,8 @@ 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, - 0, handle, BYPASS_CAPA); + rc = mdo_xattr_set(env, o, &buf, XATTR_NAME_ACL_ACCESS, + 0, handle); RETURN(rc); } @@ -99,13 +101,14 @@ int mdd_acl_set(const struct lu_env *env, struct mdd_object *obj, struct thandle *handle; posix_acl_xattr_header *head; posix_acl_xattr_entry *entry; - int rc, entry_count; + int entry_count; bool not_equiv, mode_change; mode_t mode; + int rc; 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) @@ -148,16 +151,14 @@ int mdd_acl_set(const struct lu_env *env, struct mdd_object *obj, /* whether ACL can be represented by i_mode only */ if (not_equiv) rc = mdo_xattr_set(env, obj, buf, XATTR_NAME_ACL_ACCESS, fl, - handle, mdd_object_capa(env, obj)); + handle); else - rc = mdo_xattr_del(env, obj, XATTR_NAME_ACL_ACCESS, handle, - mdd_object_capa(env, obj)); + rc = mdo_xattr_del(env, obj, XATTR_NAME_ACL_ACCESS, handle); if (rc) GOTO(unlock, rc); if (mode_change) - rc = mdo_attr_set(env, obj, la, handle, - mdd_object_capa(env, obj)); + rc = mdo_attr_set(env, obj, la, handle); /* security-replated changes may require sync */ if (S_ISDIR(mdd_object_type(obj))) @@ -165,7 +166,7 @@ int mdd_acl_set(const struct lu_env *env, struct mdd_object *obj, unlock: mdd_write_unlock(env, obj); stop: - mdd_trans_stop(env, mdd, rc, handle); + rc = mdd_trans_stop(env, mdd, rc, handle); RETURN(rc); } @@ -187,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) @@ -210,22 +211,29 @@ static int mdd_check_acl(const struct lu_env *env, struct mdd_object *obj, 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, - mdd_object_capa(env, obj)); + lu_buf_check_and_alloc(&mdd_env_info(env)->mti_xattr_buf, + MIN(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 */ @@ -301,24 +309,20 @@ check_capabilities: if (md_capable(uc, CFS_CAP_DAC_READ_SEARCH)) RETURN(0); + CDEBUG(D_SEC, "permission denied, mode %x, fsuid %u, uid %u\n", + la->la_mode, uc->uc_fsuid, la->la_uid); + 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, int mask) { struct mdd_object *mdd_pobj = NULL; struct mdd_object *mdd_cobj; struct lu_ucred *uc = NULL; struct lu_attr *pattr = NULL; struct lu_attr *cattr = MDD_ENV_VAR(env, cattr); - bool check_create; - bool check_link; - int check_unlink; - int check_rename_src, check_rename_tar; - int check_vtx_part, check_vtx_full; - int check_rgetfacl; int rc = 0; ENTRY; @@ -326,93 +330,28 @@ int mdd_permission(const struct lu_env *env, if (pobj != NULL) { mdd_pobj = md2mdd_obj(pobj); pattr = MDD_ENV_VAR(env, pattr); - rc = mdd_la_get(env, mdd_pobj, pattr, BYPASS_CAPA); + rc = mdd_la_get(env, mdd_pobj, pattr); if (rc) RETURN(rc); } mdd_cobj = md2mdd_obj(cobj); - rc = mdd_la_get(env, mdd_cobj, cattr, BYPASS_CAPA); + rc = mdd_la_get(env, mdd_cobj, cattr); 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); - - check_create = mask & MAY_CREATE; - check_link = mask & MAY_LINK; - check_unlink = mask & MAY_UNLINK; - check_rename_src = mask & MAY_RENAME_SRC; - check_rename_tar = mask & MAY_RENAME_TAR; - check_vtx_part = mask & MAY_VTX_PART; - check_vtx_full = mask & MAY_VTX_FULL; - check_rgetfacl = mask & MAY_RGETFACL; - - mask &= ~(MAY_CREATE | MAY_LINK | - MAY_UNLINK | - MAY_RENAME_SRC | MAY_RENAME_TAR | - MAY_VTX_PART | MAY_VTX_FULL | - MAY_RGETFACL); - - rc = mdd_permission_internal_locked(env, mdd_cobj, cattr, mask, - MOR_TGT_CHILD); - - if (!rc && check_create) - rc = mdd_may_create(env, mdd_pobj, pattr, mdd_cobj, true); - - if (!rc && check_unlink) - rc = mdd_may_unlink(env, mdd_pobj, pattr, cattr); - - if (!rc && (check_rename_src || check_rename_tar)) - rc = mdd_may_delete(env, mdd_pobj, pattr, mdd_cobj, cattr, NULL, - 1, check_rename_tar); - - if (!rc && (check_vtx_part || check_vtx_full)) { - uc = lu_ucred_assert(env); - - if (!(cattr->la_mode & S_ISVTX) || - (cattr->la_uid == uc->uc_fsuid) || - (check_vtx_full && (ma->ma_attr.la_valid & LA_UID) && - (ma->ma_attr.la_uid == uc->uc_fsuid))) { - ma->ma_attr_flags |= MDS_VTX_BYPASS; - } else { - ma->ma_attr_flags &= ~MDS_VTX_BYPASS; - if (check_vtx_full) - rc = -EPERM; - } - } + rc = mdd_permission_internal_locked(env, mdd_cobj, cattr, + mask & ~MAY_RGETFACL, + MOR_TGT_CHILD); - if (unlikely(!rc && check_rgetfacl)) { - if (likely(!uc)) + if (unlikely(rc == 0 && (mask & MAY_RGETFACL))) { + if (likely(!uc)) uc = lu_ucred_assert(env); if (cattr->la_uid != uc->uc_fsuid && !md_capable(uc, CFS_CAP_FOWNER)) rc = -EPERM; - } - - RETURN(rc); -} - -int mdd_capa_get(const struct lu_env *env, struct md_object *obj, - struct lustre_capa *capa, int renewal) -{ - struct mdd_object *mdd_obj = md2mdd_obj(obj); - struct obd_capa *oc; - int rc = 0; - ENTRY; - - oc = mdo_capa_get(env, mdd_obj, renewal ? capa : NULL, - capa->lc_opc); - if (IS_ERR(oc)) { - rc = PTR_ERR(oc); - } else if (likely(oc != NULL)) { - capa_cpy(capa, oc); - capa_put(oc); - } + } - RETURN(rc); + RETURN(rc); }