Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
/*
 * 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);
}
Exemplo n.º 4
0
/*
 * 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);
}