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); }
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); }
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); }
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); }
/* * 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); }
/* 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); }
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); }
/* * 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); }
/* * 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)); }