static void tcp_chr_connect(void *opaque) { Chardev *chr = CHARDEV(opaque); SocketChardev *s = SOCKET_CHARDEV(opaque); g_free(chr->filename); chr->filename = sockaddr_to_str( &s->sioc->localAddr, s->sioc->localAddrLen, &s->sioc->remoteAddr, s->sioc->remoteAddrLen, s->is_listen, s->is_telnet); s->connected = 1; if (s->ioc) { chr->fd_in_tag = io_add_watch_poll(chr, s->ioc, tcp_chr_read_poll, tcp_chr_read, chr, NULL); } qemu_chr_be_generic_open(chr); }
static void tcp_chr_connect(void *opaque) { Chardev *chr = CHARDEV(opaque); SocketChardev *s = SOCKET_CHARDEV(opaque); g_free(chr->filename); chr->filename = sockaddr_to_str( &s->sioc->localAddr, s->sioc->localAddrLen, &s->sioc->remoteAddr, s->sioc->remoteAddrLen, s->is_listen, s->is_telnet); s->connected = 1; if (s->ioc) { chr->gsource = io_add_watch_poll(chr, s->ioc, tcp_chr_read_poll, tcp_chr_read, chr, NULL); } qemu_chr_be_event(chr, CHR_EVENT_OPENED); }
/* * Function: it_config_setprop() * * Validate the provided property list and set the global properties * for iSCSI Target. If errlist is not NULL, returns detailed * errors for each property that failed. The format for errorlist * is key = property, value = error string. * * Parameters: * * cfg The current iSCSI configuration obtained from * it_config_load() * proplist nvlist_t containing properties for this target. * errlist (optional) nvlist_t of errors encountered when * validating the properties. * * Return Values: * 0 Success * EINVAL Invalid property * */ int it_config_setprop(it_config_t *cfg, nvlist_t *proplist, nvlist_t **errlist) { int ret; nvlist_t *errs = NULL; it_portal_t *isns = NULL; it_portal_t *pnext = NULL; it_portal_t *newisnslist = NULL; char **arr; uint32_t count; uint32_t newcount; nvlist_t *cprops = NULL; char *val = NULL; if (!cfg || !proplist) { return (EINVAL); } if (errlist) { (void) nvlist_alloc(&errs, 0, 0); *errlist = errs; } /* * copy the existing properties, merge, then validate * the merged properties before committing them. */ if (cfg->config_global_properties) { ret = nvlist_dup(cfg->config_global_properties, &cprops, 0); } else { ret = nvlist_alloc(&cprops, NV_UNIQUE_NAME, 0); } if (ret != 0) { return (ret); } ret = nvlist_merge(cprops, proplist, 0); if (ret != 0) { nvlist_free(cprops); return (ret); } /* * base64 encode the radius secret, if it's changed. */ val = NULL; (void) nvlist_lookup_string(proplist, PROP_RADIUS_SECRET, &val); if (val) { char bsecret[MAX_BASE64_LEN]; ret = it_val_pass(PROP_RADIUS_SECRET, val, errs); if (ret == 0) { (void) memset(bsecret, 0, MAX_BASE64_LEN); ret = iscsi_binary_to_base64_str((uint8_t *)val, strlen(val), bsecret, MAX_BASE64_LEN); if (ret == 0) { /* replace the value in the nvlist */ ret = nvlist_add_string(cprops, PROP_RADIUS_SECRET, bsecret); } } } if (ret != 0) { nvlist_free(cprops); return (ret); } /* see if we need to remove the radius server setting */ val = NULL; (void) nvlist_lookup_string(cprops, PROP_RADIUS_SERVER, &val); if (val && (strcasecmp(val, "none") == 0)) { (void) nvlist_remove_all(cprops, PROP_RADIUS_SERVER); } /* and/or remove the alias */ val = NULL; (void) nvlist_lookup_string(cprops, PROP_ALIAS, &val); if (val && (strcasecmp(val, "none") == 0)) { (void) nvlist_remove_all(cprops, PROP_ALIAS); } ret = it_validate_configprops(cprops, errs); if (ret != 0) { if (cprops) { nvlist_free(cprops); } return (ret); } /* * Update iSNS server list, if exists in provided property list. */ ret = nvlist_lookup_string_array(proplist, PROP_ISNS_SERVER, &arr, &count); if (ret == 0) { /* special case: if "none", remove all defined */ if (strcasecmp(arr[0], "none") != 0) { ret = it_array_to_portallist(arr, count, ISNS_DEFAULT_SERVER_PORT, &newisnslist, &newcount); } else { newisnslist = NULL; newcount = 0; (void) nvlist_remove_all(cprops, PROP_ISNS_SERVER); } if (ret == 0) { isns = cfg->config_isns_svr_list; while (isns) { pnext = isns->portal_next; free(isns); isns = pnext; } cfg->config_isns_svr_list = newisnslist; cfg->config_isns_svr_count = newcount; /* * Replace the array in the nvlist to ensure * duplicates are properly removed & port numbers * are added. */ if (newcount > 0) { int i = 0; char **newarray; newarray = malloc(sizeof (char *) * newcount); if (newarray == NULL) { ret = ENOMEM; } else { for (isns = newisnslist; isns != NULL; isns = isns->portal_next) { (void) sockaddr_to_str( &(isns->portal_addr), &(newarray[i++])); } (void) nvlist_add_string_array(cprops, PROP_ISNS_SERVER, newarray, newcount); for (i = 0; i < newcount; i++) { if (newarray[i]) { free(newarray[i]); } } free(newarray); } } } } else if (ret == ENOENT) { /* not an error */ ret = 0; } if (ret == 0) { /* replace the global properties list */ nvlist_free(cfg->config_global_properties); cfg->config_global_properties = cprops; } else { if (cprops) { nvlist_free(cprops); } } if (ret == 0) free_empty_errlist(errlist); return (ret); }
/* * Goes through the config property list and validates * each entry. If errs is non-NULL, will return explicit errors * for each property that fails validation. */ static int it_validate_configprops(nvlist_t *nvl, nvlist_t *errs) { int errcnt = 0; nvpair_t *nvp = NULL; data_type_t nvtype; char *name; char *val; struct sockaddr_storage sa; boolean_t update_rad_server = B_FALSE; char *rad_server; char *auth = NULL; if (!nvl) { return (0); } while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { name = nvpair_name(nvp); nvtype = nvpair_type(nvp); if (!name) { continue; } val = NULL; /* prefetch string value as we mostly need it */ if (nvtype == DATA_TYPE_STRING) { (void) nvpair_value_string(nvp, &val); } if (strcmp(name, PROP_ALIAS) == 0) { if (!val) { PROPERR(errs, name, gettext("must be a string value")); errcnt++; } } else if (strcmp(name, PROP_AUTH) == 0) { if (!val) { PROPERR(errs, name, gettext("must be a string value")); errcnt++; continue; } if ((strcmp(val, PA_AUTH_NONE) != 0) && (strcmp(val, PA_AUTH_CHAP) != 0) && (strcmp(val, PA_AUTH_RADIUS) != 0)) { PROPERR(errs, PROP_AUTH, gettext("must be none, chap or radius")); errcnt++; } auth = val; } else if (strcmp(name, PROP_ISNS_ENABLED) == 0) { if (nvtype != DATA_TYPE_BOOLEAN_VALUE) { PROPERR(errs, name, gettext("must be a boolean value")); errcnt++; } } else if (strcmp(name, PROP_ISNS_SERVER) == 0) { char **arr = NULL; uint32_t acount = 0; (void) nvlist_lookup_string_array(nvl, name, &arr, &acount); while (acount > 0) { if (strcasecmp(arr[acount - 1], "none") == 0) { break; } if ((it_common_convert_sa(arr[acount - 1], &sa, 0)) == NULL) { PROPERR(errs, arr[acount - 1], gettext("invalid address")); errcnt++; } acount--; } } else if (strcmp(name, PROP_RADIUS_SECRET) == 0) { if (!val) { PROPERR(errs, name, gettext("must be a string value")); errcnt++; continue; } } else if (strcmp(name, PROP_RADIUS_SERVER) == 0) { struct sockaddr_storage sa; if (!val) { PROPERR(errs, name, gettext("must be a string value")); errcnt++; continue; } if ((it_common_convert_sa(val, &sa, DEFAULT_RADIUS_PORT)) == NULL) { PROPERR(errs, name, gettext("invalid address")); errcnt++; } else { /* * rewrite this property to ensure port * number is added. */ if (sockaddr_to_str(&sa, &rad_server) == 0) { update_rad_server = B_TRUE; } } } else { /* unrecognized property */ PROPERR(errs, name, gettext("unrecognized property")); errcnt++; } } /* * If we successfully reformatted the radius server to add the port * number then update the nvlist */ if (update_rad_server) { (void) nvlist_add_string(nvl, PROP_RADIUS_SERVER, rad_server); free(rad_server); } /* * if auth = radius, ensure radius server & secret are set. */ if (auth) { if (strcmp(auth, PA_AUTH_RADIUS) == 0) { /* need server & secret for radius */ if (!nvlist_exists(nvl, PROP_RADIUS_SERVER)) { PROPERR(errs, PROP_RADIUS_SERVER, gettext("missing required property")); errcnt++; } if (!nvlist_exists(nvl, PROP_RADIUS_SECRET)) { PROPERR(errs, PROP_RADIUS_SECRET, gettext("missing required property")); errcnt++; } } } if (errcnt) { return (EINVAL); } return (0); }