static devplcyent_t * parse_policy(devplcysys_t *ds, devplcy_t *nullp, devplcy_t *defp) { devplcyent_t *de = kmem_zalloc(sizeof (*de), KM_SLEEP); devplcy_t *np; if (priv_isemptyset(&ds->dps_rdp) && priv_isemptyset(&ds->dps_wrp)) dphold(np = nullp); else if (defp != nullp && priv_isequalset(&ds->dps_rdp, &defp->dp_rdp) && priv_isequalset(&ds->dps_wrp, &defp->dp_wrp)) dphold(np = defp); else { np = dpget(); np->dp_rdp = ds->dps_rdp; np->dp_wrp = ds->dps_wrp; } if (ds->dps_minornm[0] != '\0') { de->dpe_len = strlen(ds->dps_minornm) + 1; if (strchr(ds->dps_minornm, '*') != NULL) { if (de->dpe_len == 2) { /* "*\0" */ de->dpe_flags = DPE_ALLMINOR; de->dpe_len = 0; } else de->dpe_flags = DPE_WILDC; } if (de->dpe_len != 0) { de->dpe_expr = kmem_alloc(de->dpe_len, KM_SLEEP); (void) strcpy(de->dpe_expr, ds->dps_minornm); } } else { de->dpe_lomin = ds->dps_lomin; de->dpe_himin = ds->dps_himin; de->dpe_flags = DPE_EXPANDED; de->dpe_spec = ds->dps_isblock ? VBLK : VCHR; } de->dpe_plcy = np; ASSERT((de->dpe_flags & (DPE_ALLMINOR|DPE_EXPANDED)) || de->dpe_expr != NULL); return (de); }
/* * Check to see if the door client's euid is 0 or if it has required_priv * privilege. Return 0 if yes, -1 otherwise. * Supported values for required_priv are: * - NSCD_ALL_PRIV: for all zones privileges * - NSCD_READ_PRIV: for PRIV_FILE_DAC_READ privilege */ int _nscd_check_client_priv(int required_priv) { int rc = 0; ucred_t *uc = NULL; const priv_set_t *eset; char *me = "_nscd_check_client_read_priv"; priv_set_t *zs; /* zone */ if (door_ucred(&uc) != 0) { _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) (me, "door_ucred: %s\n", strerror(errno)); return (-1); } if (ucred_geteuid(uc) == 0) { ucred_free(uc); return (0); } eset = ucred_getprivset(uc, PRIV_EFFECTIVE); switch (required_priv) { case NSCD_ALL_PRIV: zs = priv_str_to_set("zone", ",", NULL); if (!priv_isequalset(eset, zs)) { _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) (me, "missing all zones privileges\n"); rc = -1; } priv_freeset(zs); break; case NSCD_READ_PRIV: if (!priv_ismember(eset, PRIV_FILE_DAC_READ)) rc = -1; break; default: _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) (me, "unknown required_priv: %d\n", required_priv); rc = -1; break; } ucred_free(uc); return (rc); }
/* * This routine is used to compare two credentials to determine if * they refer to the same "user". If the pointers are equal, then * they must refer to the same user. Otherwise, the contents of * the credentials are compared to see whether they are equivalent. * * This routine returns 0 if the credentials refer to the same user, * 1 if they do not. */ int crcmp(const cred_t *cr1, const cred_t *cr2) { credgrp_t *grp1, *grp2; if (cr1 == cr2) return (0); if (cr1->cr_uid == cr2->cr_uid && cr1->cr_gid == cr2->cr_gid && cr1->cr_ruid == cr2->cr_ruid && cr1->cr_rgid == cr2->cr_rgid && cr1->cr_zone == cr2->cr_zone && ((grp1 = cr1->cr_grps) == (grp2 = cr2->cr_grps) || (grp1 != NULL && grp2 != NULL && grp1->crg_ngroups == grp2->crg_ngroups && bcmp(grp1->crg_groups, grp2->crg_groups, grp1->crg_ngroups * sizeof (gid_t)) == 0))) { return (!priv_isequalset(&CR_OEPRIV(cr1), &CR_OEPRIV(cr2))); } return (1); }