/** * Virtio Net device attach rountine. * * @param pDevice Pointer to the Virtio device instance. * * @return corresponding solaris error code. */ static int VirtioNetDevAttach(PVIRTIODEVICE pDevice) { LogFlowFunc((VIRTIOLOGNAME ":VirtioNetDevAttach pDevice=%p\n", pDevice)); virtio_net_t *pNet = pDevice->pvDevice; mac_register_t *pMacRegHandle = mac_alloc(MAC_VERSION); if (pMacRegHandle) { pMacRegHandle->m_driver = pDevice; pMacRegHandle->m_dip = pDevice->pDip; pMacRegHandle->m_callbacks = &g_VirtioNetCallbacks; pMacRegHandle->m_type_ident = MAC_PLUGIN_IDENT_ETHER; pMacRegHandle->m_min_sdu = 0; pMacRegHandle->m_max_sdu = 1500; /* @todo verify */ /* @todo should we set the margin size? */ pMacRegHandle->m_src_addr = pNet->MacAddr.au8; /* * Get MAC from the host or generate a random MAC address. */ if (pDevice->fHostFeatures & VIRTIO_NET_MAC) { pDevice->pHyperOps->pfnGet(pDevice, 0 /* offset */, &pNet->MacAddr.au8, sizeof(pNet->MacAddr)); LogFlow((VIRTIOLOGNAME ":VirtioNetDevAttach: Obtained MAC address from host: %.6Rhxs\n", pNet->MacAddr.au8)); } else { pNet->MacAddr.au8[0] = 0x08; pNet->MacAddr.au8[1] = 0x00; pNet->MacAddr.au8[2] = 0x27; RTRandBytes(&pNet->MacAddr.au8[3], 3); LogFlow((VIRTIOLOGNAME ":VirtioNetDevAttach: Generated MAC address %.6Rhxs\n", pNet->MacAddr.au8)); } int rc = VirtioNetAttachQueues(pDevice); if (rc == DDI_SUCCESS) { rc = mac_register(pMacRegHandle, &pNet->hMac); if (rc == 0) { mac_link_update(pNet->hMac, LINK_STATE_DOWN); mac_free(pMacRegHandle); LogFlow((VIRTIOLOGNAME ":VirtioNetDevAttach: successfully registered mac.\n")); return DDI_SUCCESS; } else LogRel((VIRTIOLOGNAME ":VirtioNetDevAttach: mac_register failed. rc=%d\n", rc)); VirtioNetDetachQueues(pDevice); } else LogRel((VIRTIOLOGNAME ":VirtioNetDevAttach: VirtioNetAttachQueues failed. rc=%d\n", rc)); mac_free(pMacRegHandle); } else LogRel((VIRTIOLOGNAME ":VirtioNetDevAttach: mac_alloc failed. Invalid version!?!\n")); return DDI_FAILURE; }
static char * lctx_label (pid_t lcid) { mac_t lctxlabel; char *string; int error; string = NULL; error = mac_prepare_process_label(&lctxlabel); if (error == -1) { warn("mac_prepare_process_label"); return (NULL); } error = mac_get_lcid(lcid, lctxlabel); if (error) { warn("mac_get_lcid"); return (NULL); } error = mac_to_text(lctxlabel, &string); if (error == -1) { mac_free(lctxlabel); return (NULL); } mac_free(lctxlabel); return (string); }
int main(int argc, char *argv[]) { char ch, *labellist, *string; mac_t label; int hflag; int error, i; labellist = NULL; hflag = 0; while ((ch = getopt(argc, argv, "hl:")) != -1) { switch (ch) { case 'h': hflag = 1; break; case 'l': if (labellist != NULL) usage(); labellist = argv[optind - 1]; break; default: usage(); } } for (i = optind; i < argc; i++) { if (labellist != NULL) error = mac_prepare(&label, labellist); else error = mac_prepare_file_label(&label); if (error != 0) { perror("mac_prepare"); return (-1); } if (hflag) error = mac_get_link (argv[i], label); else error = mac_get_file (argv[i], label); if (error) { perror(argv[i]); mac_free(label); continue; } error = mac_to_text(label, &string); if (error != 0) perror("mac_to_text"); else { printf("%s: %s\n", argv[i], string); free(string); } mac_free(label); } exit(EX_OK); }
static void maclabel_status(int s) { struct ifreq ifr; mac_t label; char *label_text; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); if (mac_prepare_ifnet_label(&label) == -1) return; ifr.ifr_ifru.ifru_data = (void *)label; if (ioctl(s, SIOCGIFMAC, &ifr) == -1) goto mac_free; if (mac_to_text(label, &label_text) == -1) goto mac_free; if (strlen(label_text) != 0) printf("\tmaclabel %s\n", label_text); free(label_text); mac_free: mac_free(label); }
boolean_t i40e_register_mac(i40e_t *i40e) { struct i40e_hw *hw = &i40e->i40e_hw_space; int status; mac_register_t *mac = mac_alloc(MAC_VERSION); if (mac == NULL) return (B_FALSE); mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER; mac->m_driver = i40e; mac->m_dip = i40e->i40e_dip; mac->m_src_addr = hw->mac.addr; mac->m_callbacks = &i40e_m_callbacks; mac->m_min_sdu = 0; mac->m_max_sdu = i40e->i40e_sdu; mac->m_margin = VLAN_TAGSZ; mac->m_priv_props = i40e_priv_props; mac->m_v12n = MAC_VIRT_LEVEL1; status = mac_register(mac, &i40e->i40e_mac_hdl); if (status != 0) i40e_error(i40e, "mac_register() returned %d", status); mac_free(mac); return (status == 0); }
static int create_labeled_file(char *filename, const char *labeltext) { mac_t mac = NULL; int fd = -1, err; int ret = 0; fd = open(filename, O_RDWR | O_CREAT, 0777); failure("Could not create test file?!"); if (!assert(fd >= 0)) goto done; failure("Couldn't convert MAC label"); if (!assert(mac_from_text(&mac, labeltext) == 0)) goto done; errno = 0; err = mac_set_fd(fd, mac); failure("mac_set_fd(): errno=%d (%s)", errno, strerror(errno)); if (assert(err == 0)) ret = 1; /* success */ done: if (mac) mac_free(mac); if (fd >= 0) close(fd); return ret; }
/* Register virtionet driver with GLDv3 framework */ static int virtionet_mac_register(virtionet_state_t *sp) { mac_register_t *mp; int rc; mp = mac_alloc(MAC_VERSION); if (mp == NULL) { return (DDI_FAILURE); } mp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; mp->m_driver = sp; mp->m_dip = sp->dip; mp->m_instance = 0; mp->m_src_addr = sp->addr; mp->m_dst_addr = NULL; mp->m_callbacks = &virtionet_mac_callbacks; mp->m_min_sdu = 0; mp->m_max_sdu = ETHERMTU; mp->m_margin = VLAN_TAGSZ; mp->m_priv_props = virtionet_priv_props; rc = mac_register(mp, &sp->mh); mac_free(mp); if (rc != 0) { return (DDI_FAILURE); } return (DDI_SUCCESS); }
int setfilecon_raw(const char *path, security_context_t context) { mac_t mac; char tmp[strlen(context) + strlen("sebsd/0")]; int r; if (mac_prepare(&mac, "sebsd")) return -1; strcpy(tmp, "sebsd/"); strcat(tmp, context); if (mac_from_text(&mac, tmp)) { mac_free(mac); return -1; } r = mac_set_file(path, mac); mac_free(mac); return r; }
void * mac_realloc(void *ptr,size_t size) { void *new_blk; if (!size || !(new_blk=mac_malloc(size))) return(nil); memcpy(new_blk,ptr,size); mac_free(ptr); return(new_blk); }
static int eib_register_with_mac(eib_t *ss, dev_info_t *dip) { mac_register_t *macp; int ret; if ((macp = mac_alloc(MAC_VERSION)) == NULL) { EIB_DPRINTF_ERR(ss->ei_instance, "eib_register_with_mac: " "mac_alloc(MAC_VERSION=%d) failed", MAC_VERSION); return (EIB_E_FAILURE); } /* * Note that when we register with mac during attach, we don't * have the mac address yet (we'll get that after we login into * the gateway) so we'll simply register a zero macaddr that * we'll overwrite later during plumb, in eib_m_start(). Likewise, * we'll also update the max-sdu with the correct MTU after we * figure it out when we login to the gateway during plumb. */ macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; macp->m_driver = ss; macp->m_dip = dip; macp->m_src_addr = eib_zero_mac; macp->m_callbacks = &eib_m_callbacks; macp->m_min_sdu = 0; macp->m_max_sdu = ETHERMTU; macp->m_margin = VLAN_TAGSZ; macp->m_priv_props = eib_pvt_props; ret = mac_register(macp, &ss->ei_mac_hdl); mac_free(macp); if (ret != 0) { EIB_DPRINTF_ERR(ss->ei_instance, "eib_register_with_mac: " "mac_register() failed, ret=%d", ret); return (EIB_E_FAILURE); } return (EIB_E_SUCCESS); }
static void setifmaclabel(const char *val, int d, int s, const struct afswtch *rafp) { struct ifreq ifr; mac_t label; int error; if (mac_from_text(&label, val) == -1) { perror(val); return; } memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_ifru.ifru_data = (void *)label; error = ioctl(s, SIOCSIFMAC, &ifr); mac_free(label); if (error == -1) perror("setifmac"); }
static int get_file_maclabel(char *filename, char *buf, size_t buflen) { mac_t mac = NULL; char *labeltext = NULL; int ret = 0; if (mac_prepare_file_label(&mac)) return 0; if (mac_get_file(filename, mac)) goto done; if (mac_to_text(mac, &labeltext) == 0) { strncpy(buf, labeltext, buflen - 1); buf[buflen - 1] = '\0'; ret = 1; } done: if (mac) mac_free(mac); if (labeltext) free(labeltext); return ret; }
static void maclabel(void) { char *string; mac_t label; int error; error = mac_prepare_process_label(&label); if (error == -1) errx(1, "mac_prepare_type: %s", strerror(errno)); error = mac_get_proc(label); if (error == -1) errx(1, "mac_get_proc: %s", strerror(errno)); error = mac_to_text(label, &string); if (error == -1) errx(1, "mac_to_text: %s", strerror(errno)); (void)printf("%s\n", string); mac_free(label); free(string); }
int main(int argc, char *argv[]) { const char *shell; mac_t label; int error; if (argc < 3) usage(); error = mac_from_text(&label, argv[1]); if (error != 0) { perror("mac_from_text"); return (-1); } error = mac_set_proc(label); if (error != 0) { perror(argv[1]); return (-1); } mac_free(label); if (argc >= 3) { execvp(argv[2], argv + 2); err(1, "%s", argv[2]); } else { if (!(shell = getenv("SHELL"))) shell = _PATH_BSHELL; execlp(shell, shell, "-i", (char *)NULL); err(1, "%s", shell); } /* NOTREACHED */ }
/* * Autoconfiguration entry points. */ int efe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { ddi_acc_handle_t pci; int types; int count; int actual; uint_t pri; efe_t *efep; mac_register_t *macp; switch (cmd) { case DDI_ATTACH: break; case DDI_RESUME: efep = ddi_get_driver_private(dip); return (efe_resume(efep)); default: return (DDI_FAILURE); } /* * PCI configuration. */ if (pci_config_setup(dip, &pci) != DDI_SUCCESS) { efe_error(dip, "unable to setup PCI configuration!"); return (DDI_FAILURE); } pci_config_put16(pci, PCI_CONF_COMM, pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_MAE | PCI_COMM_ME); pci_config_teardown(&pci); if (ddi_intr_get_supported_types(dip, &types) != DDI_SUCCESS || !(types & DDI_INTR_TYPE_FIXED)) { efe_error(dip, "fixed interrupts not supported!"); return (DDI_FAILURE); } if (ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_FIXED, &count) != DDI_SUCCESS || count != 1) { efe_error(dip, "no fixed interrupts available!"); return (DDI_FAILURE); } /* * Initialize soft state. */ efep = kmem_zalloc(sizeof (efe_t), KM_SLEEP); ddi_set_driver_private(dip, efep); efep->efe_dip = dip; if (ddi_regs_map_setup(dip, 1, (caddr_t *)&efep->efe_regs, 0, 0, &efe_regs_acc_attr, &efep->efe_regs_acch) != DDI_SUCCESS) { efe_error(dip, "unable to setup register mapping!"); goto failure; } efep->efe_rx_ring = efe_ring_alloc(efep->efe_dip, RXDESCL); if (efep->efe_rx_ring == NULL) { efe_error(efep->efe_dip, "unable to allocate rx ring!"); goto failure; } efep->efe_tx_ring = efe_ring_alloc(efep->efe_dip, TXDESCL); if (efep->efe_tx_ring == NULL) { efe_error(efep->efe_dip, "unable to allocate tx ring!"); goto failure; } if (ddi_intr_alloc(dip, &efep->efe_intrh, DDI_INTR_TYPE_FIXED, 0, count, &actual, DDI_INTR_ALLOC_STRICT) != DDI_SUCCESS || actual != count) { efe_error(dip, "unable to allocate fixed interrupt!"); goto failure; } if (ddi_intr_get_pri(efep->efe_intrh, &pri) != DDI_SUCCESS || pri >= ddi_intr_get_hilevel_pri()) { efe_error(dip, "unable to get valid interrupt priority!"); goto failure; } mutex_init(&efep->efe_intrlock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); mutex_init(&efep->efe_txlock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); /* * Initialize device. */ mutex_enter(&efep->efe_intrlock); mutex_enter(&efep->efe_txlock); efe_reset(efep); mutex_exit(&efep->efe_txlock); mutex_exit(&efep->efe_intrlock); /* Use factory address as default */ efe_getaddr(efep, efep->efe_macaddr); /* * Enable the ISR. */ if (ddi_intr_add_handler(efep->efe_intrh, efe_intr, efep, NULL) != DDI_SUCCESS) { efe_error(dip, "unable to add interrupt handler!"); goto failure; } if (ddi_intr_enable(efep->efe_intrh) != DDI_SUCCESS) { efe_error(dip, "unable to enable interrupt!"); goto failure; } /* * Allocate MII resources. */ if ((efep->efe_miih = mii_alloc(efep, dip, &efe_mii_ops)) == NULL) { efe_error(dip, "unable to allocate mii resources!"); goto failure; } /* * Allocate MAC resources. */ if ((macp = mac_alloc(MAC_VERSION)) == NULL) { efe_error(dip, "unable to allocate mac resources!"); goto failure; } macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; macp->m_driver = efep; macp->m_dip = dip; macp->m_src_addr = efep->efe_macaddr; macp->m_callbacks = &efe_m_callbacks; macp->m_min_sdu = 0; macp->m_max_sdu = ETHERMTU; macp->m_margin = VLAN_TAGSZ; if (mac_register(macp, &efep->efe_mh) != 0) { efe_error(dip, "unable to register with mac!"); goto failure; } mac_free(macp); ddi_report_dev(dip); return (DDI_SUCCESS); failure: if (macp != NULL) { mac_free(macp); } if (efep->efe_miih != NULL) { mii_free(efep->efe_miih); } if (efep->efe_intrh != NULL) { (void) ddi_intr_disable(efep->efe_intrh); (void) ddi_intr_remove_handler(efep->efe_intrh); (void) ddi_intr_free(efep->efe_intrh); } mutex_destroy(&efep->efe_txlock); mutex_destroy(&efep->efe_intrlock); if (efep->efe_tx_ring != NULL) { efe_ring_free(&efep->efe_tx_ring); } if (efep->efe_rx_ring != NULL) { efe_ring_free(&efep->efe_rx_ring); } if (efep->efe_regs_acch != NULL) { ddi_regs_map_free(&efep->efe_regs_acch); } kmem_free(efep, sizeof (efe_t)); return (DDI_FAILURE); }
int main(int argc, char *argv[]) { char *labellist, *string; mac_t label; pid_t pid; int ch, error, pid_set; pid_set = 0; pid = 0; labellist = NULL; while ((ch = getopt(argc, argv, "l:p:")) != -1) { switch (ch) { case 'l': if (labellist != NULL) usage(); labellist = argv[optind - 1]; break; case 'p': if (pid_set) usage(); pid = atoi(argv[optind - 1]); pid_set = 1; break; default: usage(); } } argc -= optind; argv += optind; if (argc != 0) usage(); if (labellist != NULL) error = mac_prepare(&label, labellist); else error = mac_prepare_process_label(&label); if (error != 0) { perror("mac_prepare"); return (-1); } if (pid_set) { error = mac_get_pid(pid, label); if (error) perror("mac_get_pid"); } else { error = mac_get_proc(label); if (error) perror("mac_get_proc"); } if (error) { mac_free(label); exit (-1); } error = mac_to_text(label, &string); if (error != 0) { perror("mac_to_text"); exit(EX_DATAERR); } if (strlen(string) > 0) printf("%s\n", string); mac_free(label); free(string); exit(EX_OK); }
/***************************************************************************** * * NAME * check_file - Make sure the specified file exists as specified. * * SYNOPSIS * check_file_retval = check_file( file, own, grp, mode ); * * file r The name of the file to be verified, changed * or created. * own r The file's owner. * grp r The file's group. * mode r The file's mode. * * DESCRIPTION * This routine determines whether <file> exists -and- is a regular file. * If the file doesn't exist, this routine will create it. * * In either case, the file's owner will be set to <own>, group will be * set to <grp>, mode will be set to <mode>, and MAC label will be set * to dbadmin (for Trusted IRIX only). * * NOTES: If the owner cannot be changed to <own> because the executing * user does NOT have permission, the error is ignored and this * routine will return a successful indication. * * Only the -low order- 9 bits of <mode> are expected to be used. * * All file descriptors opened by the processing contained in * this routine are closed -before- control is returned. * * If an error occurs and the file was NOT created, this routine * attempts to put the file back to the way it existed upon entry * to this routine. * * If an error occurs and the file was created by this routine, * it is removed -before- control is returned to the caller. * * RETURNS * 0 - If the file exists as requested. * 1 - If <own> is NOT a valid user name. * 2 - If <grp> is NOT a valid group name. * 3 - If <mode> has more than the -low order- 9 bits set. * 4 - If the file could NOT be creat()'d. * 5 - If the stat() system call failed. * 6 - If the file's mode could NOT be set as requested. * 7 - If the file's group could NOT be set as requested. * 8 - If the file's owner could NOT be set as requested. * 9 - If <file> exists -and- is NOT a regular file. * 10 - If we cannot get the mac_t structure for dbadmin. * 11 - If the file's MAC label could NOT be set as requested. * *****************************************************************************/ check_file_retval check_file( char *file, char *own, char *grp, mode_t mode ) { uid_t uid; gid_t gid; #ifdef HAVE_MAC_H mac_t mac_label; #endif /* HAVE_MAC_H */ int we_created_it = 0; check_file_retval rc = CHK_SUCCESS; int fd; struct stat stbuf; if ( ( mode & ~0777 ) != 0 ) return( CHK_BAD_MODE ); uid = name_to_uid( own ); if ( uid < 0 ) return( CHK_BAD_OWNER ); gid = name_to_gid( grp ); if ( gid < 0 ) return( CHK_BAD_GROUP ); if ( stat( file, &stbuf ) < 0 ) { if ( ( fd = creat( file, mode ) ) < 0 ) return( CHK_NOT_CREATED ); (void) close( fd ); we_created_it = 1; if ( stat( file, &stbuf ) < 0 ) rc = CHK_STAT_FAILED; } if ( rc == CHK_SUCCESS && ! ( stbuf.st_mode & S_IFREG ) ) rc = CHK_FILE_NOT_REGULAR; if ( rc == CHK_SUCCESS && stbuf.st_gid != gid ) { if ( chown( file, stbuf.st_uid, gid ) < 0 ) rc = CHK_CANNOT_SET_GROUP; } if ( rc == CHK_SUCCESS && ( stbuf.st_mode & 0777 ) != mode ) { if ( chmod( file, mode ) < 0 ) rc = CHK_CANNOT_SET_MODE; } if ( rc == CHK_SUCCESS && stbuf.st_uid != uid ) { if ( chown( file, uid, gid ) < 0 ) { if ( errno != EPERM ) rc = CHK_CANNOT_SET_OWNER; } } #ifdef HAVE_MAC_H if ( rc == CHK_SUCCESS && sysconf(_SC_MAC) ) { /* * Set the MAC label of the accounting file to dbadmin. */ if (( mac_label = mac_from_text( "dbadmin" ) ) == NULL) rc = CHK_CANNOT_GET_MAC; else if ( mac_set_file( file, mac_label ) < 0 ) rc = CHK_CANNOT_SET_MAC; mac_free( mac_label ); } #endif /* HAVE_MAC_H */ if ( rc != CHK_SUCCESS ) { if ( we_created_it == 1 ) (void) unlink( file ); else { (void) chown( file, stbuf.st_uid, stbuf.st_gid ); (void) chmod( file, ( stbuf.st_mode & 0777 ) ); } } return( rc ); }
int pcn_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { pcn_t *pcnp; mac_register_t *macp; const pcn_type_t *pcn_type; int instance = ddi_get_instance(dip); int rc; ddi_acc_handle_t pci; uint16_t venid; uint16_t devid; uint16_t svid; uint16_t ssid; switch (cmd) { case DDI_RESUME: return (pcn_ddi_resume(dip)); case DDI_ATTACH: break; default: return (DDI_FAILURE); } if (ddi_slaveonly(dip) == DDI_SUCCESS) { pcn_error(dip, "slot does not support PCI bus-master"); return (DDI_FAILURE); } if (ddi_intr_hilevel(dip, 0) != 0) { pcn_error(dip, "hilevel interrupts not supported"); return (DDI_FAILURE); } if (pci_config_setup(dip, &pci) != DDI_SUCCESS) { pcn_error(dip, "unable to setup PCI config handle"); return (DDI_FAILURE); } venid = pci_config_get16(pci, PCI_CONF_VENID); devid = pci_config_get16(pci, PCI_CONF_DEVID); svid = pci_config_get16(pci, PCI_CONF_SUBVENID); ssid = pci_config_get16(pci, PCI_CONF_SUBSYSID); if ((pcn_type = pcn_match(venid, devid)) == NULL) { pci_config_teardown(&pci); pcn_error(dip, "Unable to identify PCI card"); return (DDI_FAILURE); } if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "model", pcn_type->pcn_name) != DDI_PROP_SUCCESS) { pci_config_teardown(&pci); pcn_error(dip, "Unable to create model property"); return (DDI_FAILURE); } if (ddi_soft_state_zalloc(pcn_ssp, instance) != DDI_SUCCESS) { pcn_error(dip, "Unable to allocate soft state"); pci_config_teardown(&pci); return (DDI_FAILURE); } pcnp = ddi_get_soft_state(pcn_ssp, instance); pcnp->pcn_dip = dip; pcnp->pcn_instance = instance; pcnp->pcn_extphyaddr = -1; if (ddi_get_iblock_cookie(dip, 0, &pcnp->pcn_icookie) != DDI_SUCCESS) { pcn_error(pcnp->pcn_dip, "ddi_get_iblock_cookie failed"); ddi_soft_state_free(pcn_ssp, instance); pci_config_teardown(&pci); return (DDI_FAILURE); } mutex_init(&pcnp->pcn_xmtlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie); mutex_init(&pcnp->pcn_intrlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie); mutex_init(&pcnp->pcn_reglock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie); /* * Enable bus master, IO space, and memory space accesses */ pci_config_put16(pci, PCI_CONF_COMM, pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_ME | PCI_COMM_MAE); pci_config_teardown(&pci); if (ddi_regs_map_setup(dip, 1, (caddr_t *)&pcnp->pcn_regs, 0, 0, &pcn_devattr, &pcnp->pcn_regshandle)) { pcn_error(dip, "ddi_regs_map_setup failed"); goto fail; } if (pcn_set_chipid(pcnp, (uint32_t)ssid << 16 | (uint32_t)svid) != DDI_SUCCESS) { goto fail; } if ((pcnp->pcn_mii = mii_alloc(pcnp, dip, &pcn_mii_ops)) == NULL) goto fail; /* XXX: need to set based on device */ mii_set_pauseable(pcnp->pcn_mii, B_FALSE, B_FALSE); if ((pcn_allocrxring(pcnp) != DDI_SUCCESS) || (pcn_alloctxring(pcnp) != DDI_SUCCESS)) { pcn_error(dip, "unable to allocate DMA resources"); goto fail; } pcnp->pcn_promisc = B_FALSE; mutex_enter(&pcnp->pcn_intrlock); mutex_enter(&pcnp->pcn_xmtlock); rc = pcn_initialize(pcnp, B_TRUE); mutex_exit(&pcnp->pcn_xmtlock); mutex_exit(&pcnp->pcn_intrlock); if (rc != DDI_SUCCESS) goto fail; if (ddi_add_intr(dip, 0, NULL, NULL, pcn_intr, (caddr_t)pcnp) != DDI_SUCCESS) { pcn_error(dip, "unable to add interrupt"); goto fail; } pcnp->pcn_flags |= PCN_INTR_ENABLED; if ((macp = mac_alloc(MAC_VERSION)) == NULL) { pcn_error(pcnp->pcn_dip, "mac_alloc failed"); goto fail; } macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; macp->m_driver = pcnp; macp->m_dip = dip; macp->m_src_addr = pcnp->pcn_addr; macp->m_callbacks = &pcn_m_callbacks; macp->m_min_sdu = 0; macp->m_max_sdu = ETHERMTU; macp->m_margin = VLAN_TAGSZ; if (mac_register(macp, &pcnp->pcn_mh) == DDI_SUCCESS) { mac_free(macp); return (DDI_SUCCESS); } mac_free(macp); return (DDI_SUCCESS); fail: pcn_teardown(pcnp); return (DDI_FAILURE); }
/* * Display() takes a linked list of FTSENT structures and passes the list * along with any other necessary information to the print function. P * points to the parent directory of the display list. */ static void display(const FTSENT *p, FTSENT *list, int options) { struct stat *sp; DISPLAY d; FTSENT *cur; NAMES *np; off_t maxsize; long maxblock; uintmax_t maxinode; u_long btotal, labelstrlen, maxlen, maxnlink; u_long maxlabelstr; u_int sizelen; int maxflags; gid_t maxgroup; uid_t maxuser; size_t flen, ulen, glen; char *initmax; int entries, needstats; const char *user, *group; char *flags, *labelstr = NULL; char ngroup[STRBUF_SIZEOF(uid_t) + 1]; char nuser[STRBUF_SIZEOF(gid_t) + 1]; needstats = f_inode || f_longform || f_size; flen = 0; btotal = 0; initmax = getenv("LS_COLWIDTHS"); /* Fields match -lios order. New ones should be added at the end. */ maxlabelstr = maxblock = maxlen = maxnlink = 0; maxuser = maxgroup = maxflags = maxsize = 0; maxinode = 0; if (initmax != NULL && *initmax != '\0') { char *initmax2, *jinitmax; int ninitmax; /* Fill-in "::" as "0:0:0" for the sake of scanf. */ jinitmax = malloc(strlen(initmax) * 2 + 2); if (jinitmax == NULL) err(1, "malloc"); initmax2 = jinitmax; if (*initmax == ':') strcpy(initmax2, "0:"), initmax2 += 2; else *initmax2++ = *initmax, *initmax2 = '\0'; for (initmax++; *initmax != '\0'; initmax++) { if (initmax[-1] == ':' && initmax[0] == ':') { *initmax2++ = '0'; *initmax2++ = initmax[0]; initmax2[1] = '\0'; } else { *initmax2++ = initmax[0]; initmax2[1] = '\0'; } } if (initmax2[-1] == ':') strcpy(initmax2, "0"); ninitmax = sscanf(jinitmax, " %ju : %ld : %lu : %u : %u : %i : %jd : %lu : %lu ", &maxinode, &maxblock, &maxnlink, &maxuser, &maxgroup, &maxflags, &maxsize, &maxlen, &maxlabelstr); f_notabs = 1; switch (ninitmax) { case 0: maxinode = 0; /* FALLTHROUGH */ case 1: maxblock = 0; /* FALLTHROUGH */ case 2: maxnlink = 0; /* FALLTHROUGH */ case 3: maxuser = 0; /* FALLTHROUGH */ case 4: maxgroup = 0; /* FALLTHROUGH */ case 5: maxflags = 0; /* FALLTHROUGH */ case 6: maxsize = 0; /* FALLTHROUGH */ case 7: maxlen = 0; /* FALLTHROUGH */ case 8: maxlabelstr = 0; /* FALLTHROUGH */ #ifdef COLORLS if (!f_color) #endif f_notabs = 0; /* FALLTHROUGH */ default: break; } MAKENINES(maxinode); MAKENINES(maxblock); MAKENINES(maxnlink); MAKENINES(maxsize); free(jinitmax); } d.s_size = 0; sizelen = 0; flags = NULL; for (cur = list, entries = 0; cur; cur = cur->fts_link) { if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) { warnx("%s: %s", cur->fts_name, strerror(cur->fts_errno)); cur->fts_number = NO_PRINT; rval = 1; continue; } /* * P is NULL if list is the argv list, to which different rules * apply. */ if (p == NULL) { /* Directories will be displayed later. */ if (cur->fts_info == FTS_D && !f_listdir) { cur->fts_number = NO_PRINT; continue; } } else { /* Only display dot file if -a/-A set. */ if (cur->fts_name[0] == '.' && !f_listdot) { cur->fts_number = NO_PRINT; continue; } } if (cur->fts_namelen > maxlen) maxlen = cur->fts_namelen; if (f_octal || f_octal_escape) { u_long t = len_octal(cur->fts_name, cur->fts_namelen); if (t > maxlen) maxlen = t; } if (needstats) { sp = cur->fts_statp; if (sp->st_blocks > maxblock) maxblock = sp->st_blocks; if (sp->st_ino > maxinode) maxinode = sp->st_ino; if (sp->st_nlink > maxnlink) maxnlink = sp->st_nlink; if (sp->st_size > maxsize) maxsize = sp->st_size; btotal += sp->st_blocks; if (f_longform) { if (f_numericonly) { (void)snprintf(nuser, sizeof(nuser), "%u", sp->st_uid); (void)snprintf(ngroup, sizeof(ngroup), "%u", sp->st_gid); user = nuser; group = ngroup; } else { user = user_from_uid(sp->st_uid, 0); group = group_from_gid(sp->st_gid, 0); } if ((ulen = strlen(user)) > maxuser) maxuser = ulen; if ((glen = strlen(group)) > maxgroup) maxgroup = glen; if (f_flags) { flags = fflagstostr(sp->st_flags); if (flags != NULL && *flags == '\0') { free(flags); flags = strdup("-"); } if (flags == NULL) err(1, "fflagstostr"); flen = strlen(flags); if (flen > (size_t)maxflags) maxflags = flen; } else flen = 0; labelstr = NULL; if (f_label) { char name[PATH_MAX + 1]; mac_t label; int error; error = mac_prepare_file_label(&label); if (error == -1) { warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); goto label_out; } if (cur->fts_level == FTS_ROOTLEVEL) snprintf(name, sizeof(name), "%s", cur->fts_name); else snprintf(name, sizeof(name), "%s/%s", cur->fts_parent-> fts_accpath, cur->fts_name); if (options & FTS_LOGICAL) error = mac_get_file(name, label); else error = mac_get_link(name, label); if (error == -1) { warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); mac_free(label); goto label_out; } error = mac_to_text(label, &labelstr); if (error == -1) { warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); mac_free(label); goto label_out; } mac_free(label); label_out: if (labelstr == NULL) labelstr = strdup("-"); labelstrlen = strlen(labelstr); if (labelstrlen > maxlabelstr) maxlabelstr = labelstrlen; } else labelstrlen = 0; if ((np = malloc(sizeof(NAMES) + labelstrlen + ulen + glen + flen + 4)) == NULL) err(1, "malloc"); np->user = &np->data[0]; (void)strcpy(np->user, user); np->group = &np->data[ulen + 1]; (void)strcpy(np->group, group); if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) { sizelen = snprintf(NULL, 0, "%#jx", (uintmax_t)sp->st_rdev); if (d.s_size < sizelen) d.s_size = sizelen; } if (f_flags) { np->flags = &np->data[ulen + glen + 2]; (void)strcpy(np->flags, flags); free(flags); } if (f_label) { np->label = &np->data[ulen + glen + 2 + (f_flags ? flen + 1 : 0)]; (void)strcpy(np->label, labelstr); free(labelstr); } cur->fts_pointer = np; } } ++entries; } /* * If there are no entries to display, we normally stop right * here. However, we must continue if we have to display the * total block count. In this case, we display the total only * on the second (p != NULL) pass. */ if (!entries && (!(f_longform || f_size) || p == NULL)) return; d.list = list; d.entries = entries; d.maxlen = maxlen; if (needstats) { d.btotal = btotal; d.s_block = snprintf(NULL, 0, "%lu", howmany(maxblock, blocksize)); d.s_flags = maxflags; d.s_label = maxlabelstr; d.s_group = maxgroup; d.s_inode = snprintf(NULL, 0, "%ju", maxinode); d.s_nlink = snprintf(NULL, 0, "%lu", maxnlink); sizelen = f_humanval ? HUMANVALSTR_LEN : snprintf(NULL, 0, "%ju", maxsize); if (d.s_size < sizelen) d.s_size = sizelen; d.s_user = maxuser; } if (f_thousands) /* make space for commas */ d.s_size += (d.s_size - 1) / 3; printfcn(&d); output = 1; if (f_longform) for (cur = list; cur; cur = cur->fts_link) free(cur->fts_pointer); }
/* ARGSUSED */ int vnic_dev_create(datalink_id_t vnic_id, datalink_id_t linkid, vnic_mac_addr_type_t *vnic_addr_type, int *mac_len, uchar_t *mac_addr, int *mac_slot, uint_t mac_prefix_len, uint16_t vid, vrid_t vrid, int af, mac_resource_props_t *mrp, uint32_t flags, vnic_ioc_diag_t *diag, cred_t *credp) { vnic_t *vnic; mac_register_t *mac; int err; boolean_t is_anchor = ((flags & VNIC_IOC_CREATE_ANCHOR) != 0); char vnic_name[MAXNAMELEN]; const mac_info_t *minfop; uint32_t req_hwgrp_flag = B_FALSE; *diag = VNIC_IOC_DIAG_NONE; rw_enter(&vnic_lock, RW_WRITER); /* does a VNIC with the same id already exist? */ err = mod_hash_find(vnic_hash, VNIC_HASH_KEY(vnic_id), (mod_hash_val_t *)&vnic); if (err == 0) { rw_exit(&vnic_lock); return (EEXIST); } vnic = kmem_cache_alloc(vnic_cache, KM_NOSLEEP); if (vnic == NULL) { rw_exit(&vnic_lock); return (ENOMEM); } bzero(vnic, sizeof (*vnic)); vnic->vn_id = vnic_id; vnic->vn_link_id = linkid; vnic->vn_vrid = vrid; vnic->vn_af = af; if (!is_anchor) { if (linkid == DATALINK_INVALID_LINKID) { err = EINVAL; goto bail; } /* * Open the lower MAC and assign its initial bandwidth and * MAC address. We do this here during VNIC creation and * do not wait until the upper MAC client open so that we * can validate the VNIC creation parameters (bandwidth, * MAC address, etc) and reserve a factory MAC address if * one was requested. */ err = mac_open_by_linkid(linkid, &vnic->vn_lower_mh); if (err != 0) goto bail; /* * VNIC(vlan) over VNICs(vlans) is not supported. */ if (mac_is_vnic(vnic->vn_lower_mh)) { err = EINVAL; goto bail; } /* only ethernet support for now */ minfop = mac_info(vnic->vn_lower_mh); if (minfop->mi_nativemedia != DL_ETHER) { err = ENOTSUP; goto bail; } (void) dls_mgmt_get_linkinfo(vnic_id, vnic_name, NULL, NULL, NULL); err = mac_client_open(vnic->vn_lower_mh, &vnic->vn_mch, vnic_name, MAC_OPEN_FLAGS_IS_VNIC); if (err != 0) goto bail; /* assign a MAC address to the VNIC */ err = vnic_unicast_add(vnic, *vnic_addr_type, mac_slot, mac_prefix_len, mac_len, mac_addr, flags, diag, vid, req_hwgrp_flag); if (err != 0) { vnic->vn_muh = NULL; if (diag != NULL && req_hwgrp_flag) *diag = VNIC_IOC_DIAG_NO_HWRINGS; goto bail; } /* register to receive notification from underlying MAC */ vnic->vn_mnh = mac_notify_add(vnic->vn_lower_mh, vnic_notify_cb, vnic); *vnic_addr_type = vnic->vn_addr_type; vnic->vn_addr_len = *mac_len; vnic->vn_vid = vid; bcopy(mac_addr, vnic->vn_addr, vnic->vn_addr_len); if (vnic->vn_addr_type == VNIC_MAC_ADDR_TYPE_FACTORY) vnic->vn_slot_id = *mac_slot; /* * Set the initial VNIC capabilities. If the VNIC is created * over MACs which does not support nactive vlan, disable * VNIC's hardware checksum capability if its VID is not 0, * since the underlying MAC would get the hardware checksum * offset wrong in case of VLAN packets. */ if (vid == 0 || !mac_capab_get(vnic->vn_lower_mh, MAC_CAPAB_NO_NATIVEVLAN, NULL)) { if (!mac_capab_get(vnic->vn_lower_mh, MAC_CAPAB_HCKSUM, &vnic->vn_hcksum_txflags)) vnic->vn_hcksum_txflags = 0; } else { vnic->vn_hcksum_txflags = 0; } } /* register with the MAC module */ if ((mac = mac_alloc(MAC_VERSION)) == NULL) goto bail; mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER; mac->m_driver = vnic; mac->m_dip = vnic_get_dip(); mac->m_instance = (uint_t)-1; mac->m_src_addr = vnic->vn_addr; mac->m_callbacks = &vnic_m_callbacks; if (!is_anchor) { /* * If this is a VNIC based VLAN, then we check for the * margin unless it has been created with the force * flag. If we are configuring a VLAN over an etherstub, * we don't check the margin even if force is not set. */ if (vid == 0 || (flags & VNIC_IOC_CREATE_FORCE) != 0) { if (vid != VLAN_ID_NONE) vnic->vn_force = B_TRUE; /* * As the current margin size of the underlying mac is * used to determine the margin size of the VNIC * itself, request the underlying mac not to change * to a smaller margin size. */ err = mac_margin_add(vnic->vn_lower_mh, &vnic->vn_margin, B_TRUE); ASSERT(err == 0); } else { vnic->vn_margin = VLAN_TAGSZ; err = mac_margin_add(vnic->vn_lower_mh, &vnic->vn_margin, B_FALSE); if (err != 0) { mac_free(mac); if (diag != NULL) *diag = VNIC_IOC_DIAG_MACMARGIN_INVALID; goto bail; } } mac_sdu_get(vnic->vn_lower_mh, &mac->m_min_sdu, &mac->m_max_sdu); err = mac_mtu_add(vnic->vn_lower_mh, &mac->m_max_sdu, B_FALSE); if (err != 0) { VERIFY(mac_margin_remove(vnic->vn_lower_mh, vnic->vn_margin) == 0); mac_free(mac); if (diag != NULL) *diag = VNIC_IOC_DIAG_MACMTU_INVALID; goto bail; } vnic->vn_mtu = mac->m_max_sdu; } else { vnic->vn_margin = VLAN_TAGSZ; mac->m_min_sdu = 1; mac->m_max_sdu = ANCHOR_VNIC_MAX_MTU; vnic->vn_mtu = ANCHOR_VNIC_MAX_MTU; } mac->m_margin = vnic->vn_margin; err = mac_register(mac, &vnic->vn_mh); mac_free(mac); if (err != 0) { if (!is_anchor) { VERIFY(mac_mtu_remove(vnic->vn_lower_mh, vnic->vn_mtu) == 0); VERIFY(mac_margin_remove(vnic->vn_lower_mh, vnic->vn_margin) == 0); } goto bail; } /* Set the VNIC's MAC in the client */ if (!is_anchor) { mac_set_upper_mac(vnic->vn_mch, vnic->vn_mh, mrp); if (mrp != NULL) { if ((mrp->mrp_mask & MRP_RX_RINGS) != 0 || (mrp->mrp_mask & MRP_TX_RINGS) != 0) { req_hwgrp_flag = B_TRUE; } err = mac_client_set_resources(vnic->vn_mch, mrp); if (err != 0) { VERIFY(mac_mtu_remove(vnic->vn_lower_mh, vnic->vn_mtu) == 0); VERIFY(mac_margin_remove(vnic->vn_lower_mh, vnic->vn_margin) == 0); (void) mac_unregister(vnic->vn_mh); goto bail; } } } err = dls_devnet_create(vnic->vn_mh, vnic->vn_id, crgetzoneid(credp)); if (err != 0) { VERIFY(is_anchor || mac_margin_remove(vnic->vn_lower_mh, vnic->vn_margin) == 0); if (!is_anchor) { VERIFY(mac_mtu_remove(vnic->vn_lower_mh, vnic->vn_mtu) == 0); VERIFY(mac_margin_remove(vnic->vn_lower_mh, vnic->vn_margin) == 0); } (void) mac_unregister(vnic->vn_mh); goto bail; } /* add new VNIC to hash table */ err = mod_hash_insert(vnic_hash, VNIC_HASH_KEY(vnic_id), (mod_hash_val_t)vnic); ASSERT(err == 0); vnic_count++; /* * Now that we've enabled this VNIC, we should go through and update the * link state by setting it to our parents. */ vnic->vn_enabled = B_TRUE; if (is_anchor) { mac_link_update(vnic->vn_mh, LINK_STATE_UP); } else { mac_link_update(vnic->vn_mh, mac_client_stat_get(vnic->vn_mch, MAC_STAT_LINK_STATE)); } rw_exit(&vnic_lock); return (0); bail: rw_exit(&vnic_lock); if (!is_anchor) { if (vnic->vn_mnh != NULL) (void) mac_notify_remove(vnic->vn_mnh, B_TRUE); if (vnic->vn_muh != NULL) (void) mac_unicast_remove(vnic->vn_mch, vnic->vn_muh); if (vnic->vn_mch != NULL) mac_client_close(vnic->vn_mch, MAC_CLOSE_FLAGS_IS_VNIC); if (vnic->vn_lower_mh != NULL) mac_close(vnic->vn_lower_mh); } kmem_cache_free(vnic_cache, vnic); return (err); }
int setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned int flags) { quad_t p; mode_t mymask; login_cap_t *llc = NULL; struct sigaction sa, prevsa; struct rtprio rtp; int error; if (lc == NULL) { if (pwd != NULL && (lc = login_getpwclass(pwd)) != NULL) llc = lc; /* free this when we're done */ } if (flags & LOGIN_SETPATH) pathvars[0].def = uid ? _PATH_DEFPATH : _PATH_STDPATH; /* we need a passwd entry to set these */ if (pwd == NULL) flags &= ~(LOGIN_SETGROUP | LOGIN_SETLOGIN | LOGIN_SETMAC); /* Set the process priority */ if (flags & LOGIN_SETPRIORITY) { p = login_getcapnum(lc, "priority", LOGIN_DEFPRI, LOGIN_DEFPRI); if (p > PRIO_MAX) { rtp.type = RTP_PRIO_IDLE; rtp.prio = p - PRIO_MAX - 1; p = (rtp.prio > RTP_PRIO_MAX) ? 31 : p; if (rtprio(RTP_SET, 0, &rtp)) syslog(LOG_WARNING, "rtprio '%s' (%s): %m", pwd ? pwd->pw_name : "-", lc ? lc->lc_class : LOGIN_DEFCLASS); } else if (p < PRIO_MIN) { rtp.type = RTP_PRIO_REALTIME; rtp.prio = abs(p - PRIO_MIN + RTP_PRIO_MAX); p = (rtp.prio > RTP_PRIO_MAX) ? 1 : p; if (rtprio(RTP_SET, 0, &rtp)) syslog(LOG_WARNING, "rtprio '%s' (%s): %m", pwd ? pwd->pw_name : "-", lc ? lc->lc_class : LOGIN_DEFCLASS); } else { if (setpriority(PRIO_PROCESS, 0, (int)p) != 0) syslog(LOG_WARNING, "setpriority '%s' (%s): %m", pwd ? pwd->pw_name : "-", lc ? lc->lc_class : LOGIN_DEFCLASS); } } /* Setup the user's group permissions */ if (flags & LOGIN_SETGROUP) { if (setgid(pwd->pw_gid) != 0) { syslog(LOG_ERR, "setgid(%lu): %m", (u_long)pwd->pw_gid); login_close(llc); return (-1); } if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { syslog(LOG_ERR, "initgroups(%s,%lu): %m", pwd->pw_name, (u_long)pwd->pw_gid); login_close(llc); return (-1); } } /* Set up the user's MAC label. */ if ((flags & LOGIN_SETMAC) && mac_is_present(NULL) == 1) { const char *label_string; mac_t label; label_string = login_getcapstr(lc, "label", NULL, NULL); if (label_string != NULL) { if (mac_from_text(&label, label_string) == -1) { syslog(LOG_ERR, "mac_from_text('%s') for %s: %m", pwd->pw_name, label_string); return (-1); } if (mac_set_proc(label) == -1) error = errno; else error = 0; mac_free(label); if (error != 0) { syslog(LOG_ERR, "mac_set_proc('%s') for %s: %s", label_string, pwd->pw_name, strerror(error)); return (-1); } } } /* Set the sessions login */ if ((flags & LOGIN_SETLOGIN) && setlogin(pwd->pw_name) != 0) { syslog(LOG_ERR, "setlogin(%s): %m", pwd->pw_name); login_close(llc); return (-1); } /* Inform the kernel about current login class */ if (lc != NULL && lc->lc_class != NULL && (flags & LOGIN_SETLOGINCLASS)) { /* * XXX: This is a workaround to fail gracefully in case the kernel * does not support setloginclass(2). */ bzero(&sa, sizeof(sa)); sa.sa_handler = SIG_IGN; sigfillset(&sa.sa_mask); sigaction(SIGSYS, &sa, &prevsa); error = setloginclass(lc->lc_class); sigaction(SIGSYS, &prevsa, NULL); if (error != 0) { syslog(LOG_ERR, "setloginclass(%s): %m", lc->lc_class); #ifdef notyet login_close(llc); return (-1); #endif } } mymask = (flags & LOGIN_SETUMASK) ? umask(LOGIN_DEFUMASK) : 0; mymask = setlogincontext(lc, pwd, mymask, flags); login_close(llc); /* This needs to be done after anything that needs root privs */ if ((flags & LOGIN_SETUSER) && setuid(uid) != 0) { syslog(LOG_ERR, "setuid(%lu): %m", (u_long)uid); return (-1); /* Paranoia again */ } /* * Now, we repeat some of the above for the user's private entries */ if (getuid() == uid && (lc = login_getuserclass(pwd)) != NULL) { mymask = setlogincontext(lc, pwd, mymask, flags); login_close(lc); } /* Finally, set any umask we've found */ if (flags & LOGIN_SETUMASK) umask(mymask); return (0); }