Ejemplo n.º 1
0
void
nfscmd_args(uint_t did)
{
	mutex_enter(&nfscmd_lock);
	if (nfscmd_dh)
		door_ki_rele(nfscmd_dh);
	nfscmd_dh = door_ki_lookup(did);
	mutex_exit(&nfscmd_lock);
}
Ejemplo n.º 2
0
void
mountd_args(uint_t did)
{
	mutex_enter(&mountd_lock);
	if (mountd_dh)
		door_ki_rele(mountd_dh);
	mountd_dh = door_ki_lookup(did);
	mutex_exit(&mountd_lock);
}
Ejemplo n.º 3
0
static int
idmap_unreg(int did)
{
	door_handle_t dh = door_ki_lookup(did);
	int res;
	zone_t *zone;

	if (dh == NULL)
		return (set_errno(EINVAL));

	zone = crgetzone(CRED());
	res = idmap_unreg_dh(zone, dh);
	door_ki_rele(dh);

	if (res != 0)
		return (set_errno(res));
	return (0);
}
Ejemplo n.º 4
0
static int
idmap_reg(int did)
{
	door_handle_t dh;
	int err;
	cred_t *cr = CRED();

	if ((err = secpolicy_idmap(cr)) != 0)
		return (set_errno(err));

	dh = door_ki_lookup(did);

	if (dh == NULL)
		return (set_errno(EBADF));

	if ((err = idmap_reg_dh(crgetzone(cr), dh)) != 0)
		return (set_errno(err));

	return (0);
}
Ejemplo n.º 5
0
/*
 * iscsi_door_bind
 *
 * This function tries to connect the iscsi_door.  If it succeeds
 * it keeps the vnode.
 */
boolean_t
iscsi_door_bind(
	int		did
)
{
	door_handle_t	new_handle;

	new_handle = door_ki_lookup(did);
	if (new_handle == NULL) {
		/* The lookup failed. */
		return (B_FALSE);
	}

	/* The new handle is stored.  If we had one, it is released. */
	rw_enter(&iscsi_door_lock, RW_WRITER);
	if (iscsi_door_handle != NULL) {
		door_ki_rele(iscsi_door_handle);
	}
	iscsi_door_handle = new_handle;
	rw_exit(&iscsi_door_lock);

	return (B_TRUE);
}
Ejemplo n.º 6
0
/* ARGSUSED */
static int
pppt_drv_ioctl(dev_t drv, int cmd, intptr_t argp, int flag, cred_t *cred,
    int *retval)
{
	int				rc;
	void				*buf;
	size_t				buf_size;
	pppt_iocdata_t			iocd;
	door_handle_t			new_handle;

	if (drv_priv(cred) != 0) {
		return (EPERM);
	}

	rc = ddi_copyin((void *)argp, &iocd, sizeof (iocd), flag);
	if (rc)
		return (EFAULT);

	if (iocd.pppt_version != PPPT_VERSION_1)
		return (EINVAL);

	switch (cmd) {
	case PPPT_MESSAGE:

		/* XXX limit buf_size ? */
		buf_size = (size_t)iocd.pppt_buf_size;
		buf = kmem_alloc(buf_size, KM_SLEEP);
		if (buf == NULL)
			return (ENOMEM);

		rc = ddi_copyin((void *)(unsigned long)iocd.pppt_buf,
		    buf, buf_size, flag);
		if (rc) {
			kmem_free(buf, buf_size);
			return (EFAULT);
		}

		stmf_ic_rx_msg(buf, buf_size);

		kmem_free(buf, buf_size);
		break;
	case PPPT_INSTALL_DOOR:

		new_handle = door_ki_lookup((int)iocd.pppt_door_fd);
		if (new_handle == NULL)
			return (EINVAL);

		mutex_enter(&pppt_global.global_door_lock);
		ASSERT(pppt_global.global_svc_state == PSS_ENABLED);
		if (pppt_global.global_door != NULL) {
			/*
			 * There can only be one door installed
			 */
			mutex_exit(&pppt_global.global_door_lock);
			door_ki_rele(new_handle);
			return (EBUSY);
		}
		pppt_global.global_door = new_handle;
		mutex_exit(&pppt_global.global_door_lock);
		break;
	}

	return (rc);
}
Ejemplo n.º 7
0
int
klpd_unreg(int did, idtype_t type, id_t id)
{
	door_handle_t dh;
	int res = 0;
	proc_t *p;
	pid_t pid;
	projid_t proj;
	kproject_t *kpp = NULL;
	credklpd_t *ckp;

	switch (type) {
	case P_PID:
		pid = (pid_t)id;
		break;
	case P_PROJID:
		proj = (projid_t)id;
		kpp = project_hold_by_id(proj, crgetzone(CRED()),
		    PROJECT_HOLD_FIND);
		if (kpp == NULL)
			return (set_errno(ESRCH));
		break;
	default:
		return (set_errno(ENOTSUP));
	}

	dh = door_ki_lookup(did);
	if (dh == NULL) {
		if (kpp != NULL)
			project_rele(kpp);
		return (set_errno(EINVAL));
	}

	if (kpp != NULL) {
		mutex_enter(&klpd_mutex);
		if (kpp->kpj_klpd == NULL)
			res = ESRCH;
		else
			klpd_freelist(&kpp->kpj_klpd);
		mutex_exit(&klpd_mutex);
		project_rele(kpp);
		goto out;
	} else if ((int)pid > 0) {
		mutex_enter(&pidlock);
		p = prfind(pid);
		if (p == NULL) {
			mutex_exit(&pidlock);
			door_ki_rele(dh);
			return (set_errno(ESRCH));
		}
		mutex_enter(&p->p_crlock);
		mutex_exit(&pidlock);
	} else if (pid == 0) {
		p = curproc;
		mutex_enter(&p->p_crlock);
	} else {
		res = klpd_unreg_dh(dh);
		goto out;
	}

	ckp = crgetcrklpd(p->p_cred);
	if (ckp != NULL) {
		crklpd_setreg(ckp, NULL);
	} else {
		res = ESRCH;
	}
	mutex_exit(&p->p_crlock);

out:
	door_ki_rele(dh);

	if (res != 0)
		return (set_errno(res));
	return (0);
}
Ejemplo n.º 8
0
/*
 * Register the klpd.
 * If the pid_t passed in is positive, update the registration for
 * the specific process; that is only possible if the process already
 * has a registration on it.  This change of registration will affect
 * all processes which share common ancestry.
 *
 * MY_PID (pid 0) can be used to create or change the context for
 * the current process, typically done after fork().
 *
 * A negative value can be used to register a klpd globally.
 *
 * The per-credential klpd needs to be cleaned up when entering
 * a zone or unsetting the flag.
 */
int
klpd_reg(int did, idtype_t type, id_t id, priv_set_t *psetbuf)
{
	cred_t *cr = CRED();
	door_handle_t dh;
	klpd_reg_t *kpd;
	priv_set_t pset;
	door_info_t di;
	credklpd_t *ckp = NULL;
	pid_t pid = -1;
	projid_t proj = -1;
	kproject_t *kpp = NULL;

	if (CR_FLAGS(cr) & PRIV_XPOLICY)
		return (set_errno(EINVAL));

	if (copyin(psetbuf, &pset, sizeof (priv_set_t)))
		return (set_errno(EFAULT));

	if (!priv_issubset(&pset, &CR_OEPRIV(cr)))
		return (set_errno(EPERM));

	switch (type) {
	case P_PID:
		pid = (pid_t)id;
		if (pid == P_MYPID)
			pid = curproc->p_pid;
		if (pid == curproc->p_pid)
			ckp = crklpd_alloc();
		break;
	case P_PROJID:
		proj = (projid_t)id;
		kpp = project_hold_by_id(proj, crgetzone(cr),
		    PROJECT_HOLD_FIND);
		if (kpp == NULL)
			return (set_errno(ESRCH));
		break;
	default:
		return (set_errno(ENOTSUP));
	}


	/*
	 * Verify the door passed in; it must be a door and we won't
	 * allow processes to be called on their own behalf.
	 */
	dh = door_ki_lookup(did);
	if (dh == NULL || door_ki_info(dh, &di) != 0) {
		if (ckp != NULL)
			crklpd_rele(ckp);
		if (kpp != NULL)
			project_rele(kpp);
		return (set_errno(EBADF));
	}
	if (type == P_PID && pid == di.di_target) {
		if (ckp != NULL)
			crklpd_rele(ckp);
		ASSERT(kpp == NULL);
		return (set_errno(EINVAL));
	}

	kpd = kmem_zalloc(sizeof (*kpd), KM_SLEEP);
	crhold(kpd->klpd_cred = cr);
	kpd->klpd_door = dh;
	kpd->klpd_door_pid = di.di_target;
	kpd->klpd_ref = 1;
	kpd->klpd_pset = pset;

	if (kpp != NULL) {
		mutex_enter(&klpd_mutex);
		kpd = klpd_link(kpd, &kpp->kpj_klpd, B_TRUE);
		mutex_exit(&klpd_mutex);
		if (kpd != NULL)
			klpd_rele(kpd);
		project_rele(kpp);
	} else if ((int)pid < 0) {
		/* Global daemon */
		mutex_enter(&klpd_mutex);
		(void) klpd_link(kpd, &klpd_list, B_FALSE);
		mutex_exit(&klpd_mutex);
	} else if (pid == curproc->p_pid) {
		proc_t *p = curproc;
		cred_t *newcr = cralloc();

		/* No need to lock, sole reference to ckp */
		kpd = klpd_link(kpd, &ckp->crkl_reg, B_TRUE);

		if (kpd != NULL)
			klpd_rele(kpd);

		mutex_enter(&p->p_crlock);
		cr = p->p_cred;
		crdup_to(cr, newcr);
		crsetcrklpd(newcr, ckp);
		p->p_cred = newcr;	/* Already held for p_cred */

		crhold(newcr);		/* Hold once for the current thread */
		mutex_exit(&p->p_crlock);
		crfree(cr);		/* One for the p_cred */
		crset(p, newcr);
	} else {
		proc_t *p;
		cred_t *pcr;
		mutex_enter(&pidlock);
		p = prfind(pid);
		if (p == NULL || !prochasprocperm(p, curproc, CRED())) {
			mutex_exit(&pidlock);
			klpd_rele(kpd);
			return (set_errno(p == NULL ? ESRCH : EPERM));
		}
		mutex_enter(&p->p_crlock);
		crhold(pcr = p->p_cred);
		mutex_exit(&pidlock);
		mutex_exit(&p->p_crlock);
		/*
		 * We're going to update the credential's ckp in place;
		 * this requires that it exists.
		 */
		ckp = crgetcrklpd(pcr);
		if (ckp == NULL) {
			crfree(pcr);
			klpd_rele(kpd);
			return (set_errno(EINVAL));
		}
		crklpd_setreg(ckp, kpd);
		crfree(pcr);
	}

	return (0);
}
Ejemplo n.º 9
0
/*
 * This function is not MultiThread safe. The caller has to make sure only one
 * thread calls this function.
 */
door_handle_t
smb_kshare_door_init(int door_id)
{
	return (door_ki_lookup(door_id));
}