X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_lib.c;h=b3dc46284daa2b3c8ca671188818456eddff1456;hb=feb80fe0c440f7790cc3afa53d048370374a81b1;hp=410ad51193d993bc77eb9eecf0894114822a59e4;hpb=fd908da92ccd9aab4ffc3d2463301831260c0474;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 410ad51..b3dc462 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -1,36 +1,49 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * lustre/mdt/mdt_lib.c - * Lustre Metadata Target (mdt) request unpacking helper. + * GPL HEADER START * - * Copyright (c) 2006 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Andreas Dilger - * Author: Phil Schwan - * Author: Mike Shaver - * Author: Nikita Danilov - * Author: Huang Hua - * Author: Fan Yong + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * This file is part of the Lustre file system, http://www.lustre.org - * Lustre is a trademark of Cluster File Systems, Inc. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * You may have signed or agreed to another license before downloading - * this software. If so, you are bound by the terms and conditions - * of that agreement, and the following does not apply to you. See the - * LICENSE file included with this distribution for more information. + * 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 * - * If you did not agree to a different license, then this copy of Lustre - * is open source software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. + * 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. * - * In either case, Lustre is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * license text for more details. + * GPL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/mdt/mdt_lib.c + * + * Lustre Metadata Target (mdt) request unpacking helper. + * + * Author: Peter Braam + * Author: Andreas Dilger + * Author: Phil Schwan + * Author: Mike Shaver + * Author: Nikita Danilov + * Author: Huang Hua + * Author: Fan Yong */ @@ -83,18 +96,18 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, struct mdt_device *mdt = info->mti_mdt; struct ptlrpc_user_desc *pud = req->rq_user_desc; struct md_ucred *ucred = mdt_ucred(info); - lnet_nid_t peernid = req->rq_peer.nid; + lnet_nid_t peernid = req->rq_peer.nid; __u32 perm = 0; - int setuid; - int setgid; - int rc = 0; + int setuid; + int setgid; + int rc = 0; ENTRY; LASSERT(req->rq_auth_gss); LASSERT(!req->rq_auth_usr_mdt); LASSERT(req->rq_user_desc); - + ucred->mu_valid = UCRED_INVALID; ucred->mu_o_uid = pud->pud_uid; @@ -112,7 +125,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, /* sanity check: we expect the uid which client claimed is true */ if (med->med_rmtclient) { if (req->rq_auth_mapped_uid == INVALID_UID) { - CWARN("remote user not mapped, deny access!\n"); + CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); RETURN(-EACCES); } @@ -120,9 +133,9 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, RETURN(-EACCES); if (req->rq_auth_mapped_uid != pud->pud_uid) { - CERROR("remote client "LPU64": auth/mapped uid %u/%u " - "while client claim %u:%u/%u:%u\n", - peernid, req->rq_auth_uid, + CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u " + "while client claims %u:%u/%u:%u\n", + libcfs_nid2str(peernid), req->rq_auth_uid, req->rq_auth_mapped_uid, pud->pud_uid, pud->pud_gid, pud->pud_fsuid, pud->pud_fsgid); @@ -130,17 +143,18 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, } } else { if (req->rq_auth_uid != pud->pud_uid) { - CERROR("local client "LPU64": auth uid %u " - "while client claim %u:%u/%u:%u\n", - peernid, req->rq_auth_uid, pud->pud_uid, - pud->pud_gid, pud->pud_fsuid, pud->pud_fsgid); + CDEBUG(D_SEC, "local client %s: auth uid %u " + "while client claims %u:%u/%u:%u\n", + libcfs_nid2str(peernid), req->rq_auth_uid, + pud->pud_uid, pud->pud_gid, + pud->pud_fsuid, pud->pud_fsgid); RETURN(-EACCES); } } if (is_identity_get_disabled(mdt->mdt_identity_cache)) { if (med->med_rmtclient) { - CERROR("remote client must run with identity_get " + CDEBUG(D_SEC, "remote client must run with identity_get " "enabled!\n"); RETURN(-EACCES); } else { @@ -149,16 +163,26 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, CFS_SETGRP_PERM; } } else { - ucred->mu_identity = mdt_identity_get(mdt->mdt_identity_cache, - pud->pud_uid); - if (!ucred->mu_identity) { - CERROR("Deny access without identity: uid %d\n", - pud->pud_uid); - RETURN(-EACCES); + struct md_identity *identity; + + identity = mdt_identity_get(mdt->mdt_identity_cache, + pud->pud_uid); + if (IS_ERR(identity)) { + if (unlikely(PTR_ERR(identity) == -EREMCHG && + !med->med_rmtclient)) { + ucred->mu_identity = NULL; + perm = CFS_SETUID_PERM | CFS_SETGID_PERM | + CFS_SETGRP_PERM; + } else { + CDEBUG(D_SEC, "Deny access without identity: uid %u\n", + pud->pud_uid); + RETURN(-EACCES); + } } else { + ucred->mu_identity = identity; perm = mdt_identity_get_perm(ucred->mu_identity, - med->med_rmtclient, - peernid); + med->med_rmtclient, + peernid); } } @@ -170,17 +194,17 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, /* check permission of setuid */ if (setuid && !(perm & CFS_SETUID_PERM)) { - CWARN("mdt blocked setuid attempt (%u -> %u) from " - LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid); + CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n", + pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid)); GOTO(out, rc = -EACCES); } /* check permission of setgid */ if (setgid && !(perm & CFS_SETGID_PERM)) { - CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) " - "from "LPX64"\n", pud->pud_uid, pud->pud_gid, - pud->pud_fsuid, pud->pud_fsgid, - ucred->mu_identity->mi_gid, peernid); + CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) " + "from %s\n", pud->pud_uid, pud->pud_gid, + pud->pud_fsuid, pud->pud_fsgid, + ucred->mu_identity->mi_gid, libcfs_nid2str(peernid)); GOTO(out, rc = -EACCES); } @@ -189,20 +213,20 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, */ if (!med->med_rmtclient && perm & CFS_SETGRP_PERM) { if (pud->pud_ngroups) { - /* setgroups for local client */ + /* setgroups for local client */ ucred->mu_ginfo = groups_alloc(pud->pud_ngroups); if (!ucred->mu_ginfo) { - CERROR("failed to alloc %d groups\n", - pud->pud_ngroups); - GOTO(out, rc = -ENOMEM); - } + CERROR("failed to alloc %d groups\n", + pud->pud_ngroups); + GOTO(out, rc = -ENOMEM); + } lustre_groups_from_list(ucred->mu_ginfo, pud->pud_groups); lustre_groups_sort(ucred->mu_ginfo); - } else { - ucred->mu_ginfo = NULL; - } + } else { + ucred->mu_ginfo = NULL; + } } else { ucred->mu_suppgids[0] = -1; ucred->mu_suppgids[1] = -1; @@ -219,7 +243,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, /* remove fs privilege for non-root user */ if (ucred->mu_fsuid) - ucred->mu_cap = pud->pud_cap & ~CAP_FS_MASK; + ucred->mu_cap = pud->pud_cap & ~CFS_CAP_FS_MASK; else ucred->mu_cap = pud->pud_cap; ucred->mu_valid = UCRED_NEW; @@ -250,7 +274,7 @@ int mdt_check_ucred(struct mdt_thread_info *info) struct ptlrpc_user_desc *pud = req->rq_user_desc; struct md_ucred *ucred = mdt_ucred(info); struct md_identity *identity = NULL; - lnet_nid_t peernid = req->rq_peer.nid; + lnet_nid_t peernid = req->rq_peer.nid; __u32 perm = 0; int setuid; int setgid; @@ -266,38 +290,38 @@ int mdt_check_ucred(struct mdt_thread_info *info) /* sanity check: if we use strong authentication, we expect the * uid which client claimed is true */ - if (med->med_rmtclient) { - if (req->rq_auth_mapped_uid == INVALID_UID) { - CWARN("remote user not mapped, deny access!\n"); - RETURN(-EACCES); - } + if (med->med_rmtclient) { + if (req->rq_auth_mapped_uid == INVALID_UID) { + CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); + RETURN(-EACCES); + } - if (ptlrpc_user_desc_do_idmap(req, pud)) - RETURN(-EACCES); + if (ptlrpc_user_desc_do_idmap(req, pud)) + RETURN(-EACCES); - if (req->rq_auth_mapped_uid != pud->pud_uid) { - CERROR("remote client "LPU64": auth/mapped uid %u/%u " - "while client claim %u:%u/%u:%u\n", - peernid, req->rq_auth_uid, + if (req->rq_auth_mapped_uid != pud->pud_uid) { + CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u " + "while client claims %u:%u/%u:%u\n", + libcfs_nid2str(peernid), req->rq_auth_uid, req->rq_auth_mapped_uid, pud->pud_uid, pud->pud_gid, pud->pud_fsuid, pud->pud_fsgid); - RETURN(-EACCES); - } - } else { - if (req->rq_auth_uid != pud->pud_uid) { - CERROR("local client "LPU64": auth uid %u " - "while client claim %u:%u/%u:%u\n", - peernid, req->rq_auth_uid, pud->pud_uid, - pud->pud_gid, pud->pud_fsuid, - pud->pud_fsgid); - RETURN(-EACCES); - } + RETURN(-EACCES); + } + } else { + if (req->rq_auth_uid != pud->pud_uid) { + CDEBUG(D_SEC, "local client %s: auth uid %u " + "while client claims %u:%u/%u:%u\n", + libcfs_nid2str(peernid), req->rq_auth_uid, + pud->pud_uid, pud->pud_gid, + pud->pud_fsuid, pud->pud_fsgid); + RETURN(-EACCES); } + } if (is_identity_get_disabled(mdt->mdt_identity_cache)) { if (med->med_rmtclient) { - CERROR("remote client must run with identity_get " + CDEBUG(D_SEC, "remote client must run with identity_get " "enabled!\n"); RETURN(-EACCES); } @@ -305,9 +329,15 @@ int mdt_check_ucred(struct mdt_thread_info *info) } identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid); - if (!identity) { - CERROR("Deny access without identity: uid %d\n", pud->pud_uid); - RETURN(-EACCES); + if (IS_ERR(identity)) { + if (unlikely(PTR_ERR(identity) == -EREMCHG && + !med->med_rmtclient)) { + RETURN(0); + } else { + CDEBUG(D_SEC, "Deny access without identity: uid %u\n", + pud->pud_uid); + RETURN(-EACCES); + } } perm = mdt_identity_get_perm(identity, med->med_rmtclient, peernid); @@ -318,17 +348,17 @@ int mdt_check_ucred(struct mdt_thread_info *info) /* check permission of setuid */ if (setuid && !(perm & CFS_SETUID_PERM)) { - CWARN("mdt blocked setuid attempt (%u -> %u) from " - LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid); + CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n", + pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid)); GOTO(out, rc = -EACCES); } /* check permission of setgid */ if (setgid && !(perm & CFS_SETGID_PERM)) { - CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) " - "from "LPX64"\n", pud->pud_uid, pud->pud_gid, - pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid, - peernid); + CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) " + "from %s\n", pud->pud_uid, pud->pud_gid, + pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid, + libcfs_nid2str(peernid)); GOTO(out, rc = -EACCES); } @@ -359,10 +389,14 @@ static int old_init_ucred(struct mdt_thread_info *info, if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { identity = mdt_identity_get(mdt->mdt_identity_cache, uc->mu_fsuid); - if (!identity) { - CERROR("Deny access without identity: uid %d\n", - uc->mu_fsuid); - RETURN(-EACCES); + if (IS_ERR(identity)) { + if (unlikely(PTR_ERR(identity) == -EREMCHG)) { + identity = NULL; + } else { + CDEBUG(D_SEC, "Deny access without identity: " + "uid %u\n", uc->mu_fsuid); + RETURN(-EACCES); + } } } uc->mu_identity = identity; @@ -372,7 +406,7 @@ static int old_init_ucred(struct mdt_thread_info *info, /* remove fs privilege for non-root user */ if (uc->mu_fsuid) - uc->mu_cap = body->capability & ~CAP_FS_MASK; + uc->mu_cap = body->capability & ~CFS_CAP_FS_MASK; else uc->mu_cap = body->capability; uc->mu_valid = UCRED_OLD; @@ -395,11 +429,15 @@ static int old_init_ucred_reint(struct mdt_thread_info *info) if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { identity = mdt_identity_get(mdt->mdt_identity_cache, uc->mu_fsuid); - if (!identity) { - CERROR("Deny access without identity: uid %d\n", - uc->mu_fsuid); - RETURN(-EACCES); - } + if (IS_ERR(identity)) { + if (unlikely(PTR_ERR(identity) == -EREMCHG)) { + identity = NULL; + } else { + CDEBUG(D_SEC, "Deny access without identity: " + "uid %u\n", uc->mu_fsuid); + RETURN(-EACCES); + } + } } uc->mu_identity = identity; @@ -408,7 +446,7 @@ static int old_init_ucred_reint(struct mdt_thread_info *info) /* remove fs privilege for non-root user */ if (uc->mu_fsuid) - uc->mu_cap &= ~CAP_FS_MASK; + uc->mu_cap &= ~CFS_CAP_FS_MASK; uc->mu_valid = UCRED_OLD; RETURN(0); @@ -487,7 +525,7 @@ void mdt_shrink_reply(struct mdt_thread_info *info) acl_size = body->aclsize; - CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d" + CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d" " MDSCAPA = "LPX64", OSSCAPA = "LPX64"\n", md_size, acl_size, body->valid & OBD_MD_FLMDSCAPA, @@ -508,14 +546,14 @@ void mdt_shrink_reply(struct mdt_thread_info *info) req_capsule_shrink(pill, &RMF_ACL, acl_size, RCL_SERVER); else if (req_capsule_has_field(pill, &RMF_LOGCOOKIES, RCL_SERVER)) req_capsule_shrink(pill, &RMF_LOGCOOKIES, - acl_size, RCL_SERVER); + acl_size, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_CAPA1, RCL_SERVER) && - !(body->valid & OBD_MD_FLMDSCAPA)) + !(body->valid & OBD_MD_FLMDSCAPA)) req_capsule_shrink(pill, &RMF_CAPA1, 0, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) && - !(body->valid & OBD_MD_FLOSSCAPA)) + !(body->valid & OBD_MD_FLOSSCAPA)) req_capsule_shrink(pill, &RMF_CAPA2, 0, RCL_SERVER); /* @@ -643,7 +681,10 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr, out |= LA_FLAGS; if (in & MDS_OPEN_OWNEROVERRIDE) - out |= MDS_OPEN_OWNEROVERRIDE; + ma->ma_attr_flags |= MDS_OPEN_OWNEROVERRIDE; + + if (in & (ATTR_KILL_SUID|ATTR_KILL_SGID)) + ma->ma_attr_flags |= MDS_PERM_BYPASS; /*XXX need ATTR_RAW?*/ in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_BLOCKS| @@ -717,7 +758,7 @@ static inline int mdt_dlmreq_unpack(struct mdt_thread_info *info) { if (info->mti_dlm_req == NULL) RETURN(-EFAULT); } - + RETURN(0); } @@ -810,7 +851,7 @@ static int mdt_create_unpack(struct mdt_thread_info *info) rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, RCL_CLIENT) - 1; LASSERT(rr->rr_name && rr->rr_namelen > 0); - + #ifdef CONFIG_FS_POSIX_ACL if (sp->sp_cr_flags & MDS_CREATE_RMT_ACL) { if (S_ISDIR(attr->la_mode)) @@ -1113,11 +1154,13 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) uc->mu_fsuid = rec->sx_fsuid; uc->mu_fsgid = rec->sx_fsgid; uc->mu_cap = rec->sx_cap; - uc->mu_suppgids[0] = uc->mu_suppgids[1] = -1; + uc->mu_suppgids[0] = rec->sx_suppgid1; + uc->mu_suppgids[1] = -1; rr->rr_opcode = rec->sx_opcode; rr->rr_fid1 = &rec->sx_fid; attr->la_valid = rec->sx_valid; + attr->la_ctime = rec->sx_time; attr->la_size = rec->sx_size; attr->la_flags = rec->sx_flags;