Example #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);
}
Example #2
0
File: mdt_lib.c Project: 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);
}
Example #3
0
File: mdt_lib.c Project: 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;
}