/* * Get the label if any of a zfs filesystem. Get the dataset, then * get its mlslabel property, convert as needed, and return it. If * there's no mlslabel or it is the default one, return NULL. */ static ts_label_t * getflabel_zfs(vfs_t *vfsp) { int error; ts_label_t *tsl = NULL; refstr_t *resource_ref; bslabel_t ds_sl; char ds_hexsl[MAXNAMELEN]; const char *osname; resource_ref = vfs_getresource(vfsp); osname = refstr_value(resource_ref); error = dsl_prop_get(osname, zfs_prop_to_name(ZFS_PROP_MLSLABEL), 1, sizeof (ds_hexsl), &ds_hexsl, NULL); refstr_rele(resource_ref); if ((error) || (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0)) return (NULL); if (hexstr_to_label(ds_hexsl, &ds_sl) != 0) return (NULL); tsl = labelalloc(&ds_sl, default_doi, KM_SLEEP); return (tsl); }
/* * Initialize labels infrastructure. * This is called during startup() time (before vfs_mntroot) by thread_init(). * It has to be called early so that the is_system_labeled() function returns * the right value when called by the networking code on a diskless boot. */ void label_init(void) { bslabel_t label; /* * sys_labeling will default to "off" unless it is overridden * in /etc/system. */ tslabel_cache = kmem_cache_create("tslabel_cache", sizeof (ts_label_t), 0, NULL, NULL, NULL, NULL, NULL, 0); bsllow(&label); l_admin_low = labelalloc(&label, default_doi, KM_SLEEP); bslhigh(&label); l_admin_high = labelalloc(&label, default_doi, KM_SLEEP); }
static ts_label_t * getflabel_nfs(vfs_t *vfsp) { bslabel_t *server_sl; ts_label_t *srv_label; tsol_tpc_t *tp; int addr_type; void *ipaddr; struct servinfo *svp; struct netbuf *addr; struct knetconfig *knconf; mntinfo_t *mi; mi = VFTOMI(vfsp); svp = mi->mi_curr_serv; addr = &svp->sv_addr; knconf = svp->sv_knconf; if (strcmp(knconf->knc_protofmly, NC_INET) == 0) { addr_type = IPV4_VERSION; /* LINTED: following cast to ipaddr is OK */ ipaddr = &((struct sockaddr_in *)addr->buf)->sin_addr; } else if (strcmp(knconf->knc_protofmly, NC_INET6) == 0) { addr_type = IPV6_VERSION; /* LINTED: following cast to ipaddr is OK */ ipaddr = &((struct sockaddr_in6 *)addr->buf)->sin6_addr; } else { goto errout; } tp = find_tpc(ipaddr, addr_type, B_FALSE); if (tp == NULL) goto errout; if (tp->tpc_tp.host_type == SUN_CIPSO) { TPC_RELE(tp); return (getflabel_cipso(vfsp)); } if (tp->tpc_tp.host_type != UNLABELED) goto errout; server_sl = &tp->tpc_tp.tp_def_label; srv_label = labelalloc(server_sl, default_doi, KM_SLEEP); TPC_RELE(tp); return (srv_label); errout: return (NULL); }
/* * Derive a new cred from the existing cred, but with a different label. */ cred_t * copycred_from_bslabel(const cred_t *cr, bslabel_t *blabel, uint32_t doi, int flags) { ts_label_t *lbl = labelalloc(blabel, doi, flags); cred_t *newcr = NULL; if (lbl != NULL) { newcr = copycred_from_tslabel(cr, lbl, flags); label_rele(lbl); } return (newcr); }
/* * Create a new cred based on the supplied label */ cred_t * newcred_from_bslabel(bslabel_t *blabel, uint32_t doi, int flags) { ts_label_t *lbl = labelalloc(blabel, doi, flags); cred_t *cr = NULL; if (lbl != NULL) { if ((cr = crdup_flags(dummycr, flags)) != NULL) { cr->cr_label = lbl; } else { label_rele(lbl); } } return (cr); }