Esempio n. 1
0
static int old_init_ucred(struct mdt_thread_info *info,
			  struct mdt_body *body)
{
	struct lu_ucred *uc = mdt_ucred(info);
	struct mdt_device  *mdt = info->mti_mdt;
	struct md_identity *identity = NULL;

	ENTRY;

	LASSERT(uc != NULL);
	uc->uc_valid = UCRED_INVALID;
	uc->uc_o_uid = uc->uc_uid = body->uid;
	uc->uc_o_gid = uc->uc_gid = body->gid;
	uc->uc_o_fsuid = uc->uc_fsuid = body->fsuid;
	uc->uc_o_fsgid = uc->uc_fsgid = body->fsgid;
	uc->uc_suppgids[0] = body->suppgid;
	uc->uc_suppgids[1] = -1;
	uc->uc_ginfo = NULL;
	if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
		identity = mdt_identity_get(mdt->mdt_identity_cache,
					    uc->uc_fsuid);
		if (IS_ERR(identity)) {
			if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
				identity = NULL;
			} else {
				CDEBUG(D_SEC, "Deny access without identity: "
				       "uid %u\n", uc->uc_fsuid);
				RETURN(-EACCES);
			}
		}
	}
	uc->uc_identity = identity;

	/* process root_squash here. */
	mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);

	/* remove fs privilege for non-root user. */
	if (uc->uc_fsuid)
		uc->uc_cap = body->capability & ~CFS_CAP_FS_MASK;
	else
		uc->uc_cap = body->capability;
	uc->uc_valid = UCRED_OLD;

	RETURN(0);
}
Esempio n. 2
0
File: mdt_lib.c Progetto: hpc/lustre
static int old_init_ucred_reint(struct mdt_thread_info *info)
{
        struct md_ucred *uc = mdt_ucred(info);
        struct mdt_device  *mdt = info->mti_mdt;
        struct md_identity *identity = NULL;

        ENTRY;

        uc->mu_valid = UCRED_INVALID;
        uc->mu_o_uid = uc->mu_o_fsuid = uc->mu_uid = uc->mu_fsuid;
        uc->mu_o_gid = uc->mu_o_fsgid = uc->mu_gid = uc->mu_fsgid;
        uc->mu_ginfo = NULL;
        if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
                identity = mdt_identity_get(mdt->mdt_identity_cache,
                                            uc->mu_fsuid);
                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;

        /* process root_squash here. */
        mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);

        /* remove fs privilege for non-root user. */
        if (uc->mu_fsuid)
                uc->mu_cap &= ~CFS_CAP_FS_MASK;
        uc->mu_valid = UCRED_OLD;

        RETURN(0);
}
Esempio n. 3
0
File: mdt_lib.c Progetto: hpc/lustre
int mdt_check_ucred(struct mdt_thread_info *info)
{
        struct ptlrpc_request   *req = mdt_info_req(info);
        struct mdt_device       *mdt = info->mti_mdt;
        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;
        __u32                    perm = 0;
        __u32                    remote = exp_connect_rmtclient(info->mti_exp);
        int                      setuid;
        int                      setgid;
        int                      rc = 0;

        ENTRY;

        if ((ucred->mu_valid == UCRED_OLD) || (ucred->mu_valid == UCRED_NEW))
                RETURN(0);

        if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
                RETURN(0);

        /* sanity check: if we use strong authentication, we expect the
         * uid which client claimed is true */
        if (remote) {
                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 (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) {
                        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 (remote) {
                        CDEBUG(D_SEC, "remote client must run with identity_get "
                               "enabled!\n");
                        RETURN(-EACCES);
                }
                RETURN(0);
        }

        identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
        if (IS_ERR(identity)) {
                if (unlikely(PTR_ERR(identity) == -EREMCHG &&
                             !remote)) {
                        RETURN(0);
                } else {
                        CDEBUG(D_SEC, "Deny access without identity: uid %u\n",
                               pud->pud_uid);
                        RETURN(-EACCES);
               }
        }

        perm = mdt_identity_get_perm(identity, remote, peernid);
        /* find out the setuid/setgid attempt */
        setuid = (pud->pud_uid != pud->pud_fsuid);
        setgid = (pud->pud_gid != pud->pud_fsgid ||
                  pud->pud_gid != identity->mi_gid);

        /* check permission of setuid */
        if (setuid && !(perm & CFS_SETUID_PERM)) {
                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)) {
                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);
        }

        EXIT;

out:
        mdt_identity_put(mdt->mdt_identity_cache, identity);
        return rc;
}
Esempio n. 4
0
File: mdt_lib.c Progetto: hpc/lustre
static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                          void *buf)
{
        struct ptlrpc_request   *req = mdt_info_req(info);
        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;
        __u32                    perm = 0;
        __u32                    remote = exp_connect_rmtclient(info->mti_exp);
        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;
        ucred->mu_o_gid   = pud->pud_gid;
        ucred->mu_o_fsuid = pud->pud_fsuid;
        ucred->mu_o_fsgid = pud->pud_fsgid;

        if (type == BODY_INIT) {
                struct mdt_body *body = (struct mdt_body *)buf;

                ucred->mu_suppgids[0] = body->suppgid;
                ucred->mu_suppgids[1] = -1;
        }

        /* sanity check: we expect the uid which client claimed is true */
        if (remote) {
                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 (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) {
                        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 (remote) {
                        CDEBUG(D_SEC, "remote client must run with identity_get "
                               "enabled!\n");
                        RETURN(-EACCES);
                } else {
                        ucred->mu_identity = NULL;
                        perm = CFS_SETUID_PERM | CFS_SETGID_PERM |
                               CFS_SETGRP_PERM;
                }
        } else {
                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 &&
                                     !remote)) {
                                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,
                                                     remote, peernid);
                }
        }

        /* find out the setuid/setgid attempt */
        setuid = (pud->pud_uid != pud->pud_fsuid);
        setgid = ((pud->pud_gid != pud->pud_fsgid) ||
                  (ucred->mu_identity &&
                  (pud->pud_gid != ucred->mu_identity->mi_gid)));

        /* check permission of setuid */
        if (setuid && !(perm & CFS_SETUID_PERM)) {
                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)) {
                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);
        }

        /*
         * NB: remote client not allowed to setgroups anyway.
         */
        if (!remote && perm & CFS_SETGRP_PERM) {
                if (pud->pud_ngroups) {
                        /* setgroups for local client */
                        ucred->mu_ginfo = cfs_groups_alloc(pud->pud_ngroups);
                        if (!ucred->mu_ginfo) {
                                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_suppgids[0] = -1;
                ucred->mu_suppgids[1] = -1;
                ucred->mu_ginfo = NULL;
        }

        ucred->mu_uid   = pud->pud_uid;
        ucred->mu_gid   = pud->pud_gid;
        ucred->mu_fsuid = pud->pud_fsuid;
        ucred->mu_fsgid = pud->pud_fsgid;

        /* process root_squash here. */
        mdt_root_squash(info, peernid);

        /* remove fs privilege for non-root user. */
        if (ucred->mu_fsuid)
                ucred->mu_cap = pud->pud_cap & ~CFS_CAP_FS_MASK;
        else
                ucred->mu_cap = pud->pud_cap;
        if (remote && !(perm & CFS_RMTOWN_PERM))
                ucred->mu_cap &= ~(CFS_CAP_SYS_RESOURCE_MASK |
                                   CFS_CAP_CHOWN_MASK);
        ucred->mu_valid = UCRED_NEW;

        EXIT;

out:
        if (rc) {
                if (ucred->mu_ginfo) {
                        cfs_put_group_info(ucred->mu_ginfo);
                        ucred->mu_ginfo = NULL;
                }
                if (ucred->mu_identity) {
                        mdt_identity_put(mdt->mdt_identity_cache,
                                         ucred->mu_identity);
                        ucred->mu_identity = NULL;
                }
        }

        return rc;
}
Esempio n. 5
0
int mdt_handle_idmap(struct mdt_thread_info *info)
{
        struct ptlrpc_request *req = mdt_info_req(info);
        struct mdt_device *mdt = info->mti_mdt;
        struct mdt_export_data *med;
        struct ptlrpc_user_desc *pud = req->rq_user_desc;
        struct md_identity *identity;
        __u32 opc;
        int rc = 0;
        ENTRY;

        if (!req->rq_export)
                RETURN(0);

        med = mdt_req2med(req);
        if (!exp_connect_rmtclient(info->mti_exp))
                RETURN(0);

        opc = lustre_msg_get_opc(req->rq_reqmsg);
        /* Bypass other opc */
        if ((opc != SEC_CTX_INIT) && (opc != SEC_CTX_INIT_CONT) &&
            (opc != SEC_CTX_FINI) && (opc != MDS_CONNECT))
                RETURN(0);

        LASSERT(med->med_idmap);

        if (unlikely(!pud)) {
                CDEBUG(D_SEC, "remote client must run with rq_user_desc "
                       "present\n");
                RETURN(-EACCES);
        }

        if (req->rq_auth_mapped_uid == INVALID_UID) {
                CDEBUG(D_SEC, "invalid authorized mapped uid, please check "
                       "/etc/lustre/idmap.conf!\n");
                RETURN(-EACCES);
        }

        if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
                CDEBUG(D_SEC, "remote client must run with identity_get "
                       "enabled!\n");
                RETURN(-EACCES);
        }

        identity = mdt_identity_get(mdt->mdt_identity_cache,
                                    req->rq_auth_mapped_uid);
        if (IS_ERR(identity)) {
                CDEBUG(D_SEC, "can't get mdt identity(%u), no mapping added\n",
                       req->rq_auth_mapped_uid);
                RETURN(-EACCES);
        }

        switch (opc) {
                case SEC_CTX_INIT:
                case SEC_CTX_INIT_CONT:
                case MDS_CONNECT:
                        rc = lustre_idmap_add(med->med_idmap,
                                              pud->pud_uid, identity->mi_uid,
                                              pud->pud_gid, identity->mi_gid);
                        break;
                case SEC_CTX_FINI:
                        rc = lustre_idmap_del(med->med_idmap,
                                              pud->pud_uid, identity->mi_uid,
                                              pud->pud_gid, identity->mi_gid);
                        break;
        }

        mdt_identity_put(mdt->mdt_identity_cache, identity);

        if (rc)
                RETURN(rc);

        switch (opc) {
                case SEC_CTX_INIT:
                case SEC_CTX_INIT_CONT:
                case SEC_CTX_FINI:
                        mdt_revoke_export_locks(req->rq_export);
                        break;
        }

        RETURN(0);
}