/**
 * Check the server name to find port info first
 * return 1 when found, else 0
 * Warning: connect_info-> & login-> are all modified when needed
 */
static int
parse_server_name_for_port(TDSCONNECTINFO * connect_info, TDSLOGIN * login)
{
	char *pSep, *pEnd;
	char *server;

	/* seek the ':' in login server_name */
	server = tds_dstr_cstr(&login->server_name);
	pEnd = server + strlen(server);
	for (pSep = server; pSep < pEnd; pSep++)
		if (*pSep == ':')
			break;

	if ((pSep < pEnd) && (pSep != server)) {	/* yes, i found it! */
		if (!tds_dstr_copyn(&connect_info->server_name, server, pSep - server))	/* end the server_name before the ':' */
			return 0;	/* FALSE */

		/* modify connect_info-> && login->server_name & ->port */
		login->port = connect_info->port = atoi(pSep + 1);
		*pSep = 0;

		/* connect_info->ip_addr needed */
		{
			char tmp[256];

			tds_lookup_host(tds_dstr_cstr(&connect_info->server_name), tmp);
			if (!tds_dstr_copy(&connect_info->ip_addr, tmp))
				return 0;	/* FALSE */
		}

		return 1;	/* TRUE */
	} else
		return 0;	/* FALSE */
}
Exemple #2
0
/**
 * Check the server name to find port info first
 * Warning: connection-> & login-> are all modified when needed
 * \return 1 when found, else 0
 */
static int
parse_server_name_for_port(TDSLOGIN * connection, TDSLOGIN * login)
{
	const char *pSep;
	const char *server;

	/* seek the ':' in login server_name */
	server = tds_dstr_cstr(&login->server_name);

	/* IPv6 address can be quoted */
	if (server[0] == '[') {
		pSep = strstr(server, "]:");
		if (pSep)
			++pSep;
	} else {
		pSep = strrchr(server, ':');
	}

	if (pSep && pSep != server) {	/* yes, i found it! */
		/* modify connection-> && login->server_name & ->port */
		login->port = connection->port = atoi(pSep + 1);
		tds_dstr_empty(&connection->instance_name);
	} else {
		/* handle instance name */
		pSep = strrchr(server, '\\');
		if (!pSep || pSep == server)
			return 0;

		if (!tds_dstr_copy(&connection->instance_name, pSep + 1))
			return 0;
		connection->port = 0;
	}

	if (!tds_dstr_copyn(&connection->server_name, server, pSep - server))
		return 0;

	return 1;
}
/** 
 * Parse connection string and fill connect_info according
 * @param connect_string     connect string
 * @param connect_string_end connect string end (pointer to char past last)
 * @param connect_info       where to store connection info
 * @return 1 if success 0 otherwhise
 */
int
odbc_parse_connect_string(const char *connect_string, const char *connect_string_end, TDSCONNECTINFO * connect_info)
{
	const char *p, *end;
	DSTR *dest_s, value;
	int reparse = 0;	/* flag for indicate second parse of string */
	char option[16];
	char tmp[256];

	tds_dstr_init(&value);
	for (p = connect_string; p && *p;) {
		dest_s = NULL;

		/* parse option */
		end = (const char *) memchr(p, '=', connect_string_end - p);
		if (!end)
			break;

		/* account for spaces between ;'s. */
		while (p < end && *p == ' ')
			++p;

		if ((end - p) >= (int) sizeof(option))
			option[0] = 0;
		else {
			memcpy(option, p, end - p);
			option[end - p] = 0;
		}

		/* parse value */
		p = end + 1;
		if (*p == '{') {
			++p;
			/* search "};" */
			end = p;
			while ((end = (const char *) memchr(end, '}', connect_string_end - end)) != NULL) {
				if ((end + 1) != connect_string_end && end[1] == ';')
					break;
				++end;
			}
		} else {
			end = (const char *) memchr(p, ';', connect_string_end - p);
		}
		if (!end)
			end = connect_string_end;

		if (!tds_dstr_copyn(&value, p, end - p))
			return 0;

		if (strcasecmp(option, "SERVER") == 0) {
			/* ignore if servername specified */
			if (!reparse) {
				dest_s = &connect_info->server_name;
				tds_lookup_host(tds_dstr_cstr(&value), tmp);
				if (!tds_dstr_copy(&connect_info->ip_addr, tmp)) {
					tds_dstr_free(&value);
					return 0;
				}
			}
		} else if (strcasecmp(option, "SERVERNAME") == 0) {
			if (!reparse) {
				tds_read_conf_file(connect_info, tds_dstr_cstr(&value));
				reparse = 1;
				p = connect_string;
				continue;
			}
		} else if (strcasecmp(option, "DSN") == 0) {
			if (!reparse) {
				odbc_get_dsn_info(tds_dstr_cstr(&value), connect_info);
				reparse = 1;
				p = connect_string;
				continue;
			}
		} else if (strcasecmp(option, "DATABASE") == 0) {
			dest_s = &connect_info->database;
		} else if (strcasecmp(option, "UID") == 0) {
			dest_s = &connect_info->user_name;
		} else if (strcasecmp(option, "PWD") == 0) {
			dest_s = &connect_info->password;
		} else if (strcasecmp(option, "APP") == 0) {
			dest_s = &connect_info->app_name;
		} else if (strcasecmp(option, "WSID") == 0) {
			dest_s = &connect_info->host_name;
		} else if (strcasecmp(option, "LANGUAGE") == 0) {
			dest_s = &connect_info->language;
		} else if (strcasecmp(option, "Port") == 0) {
			connect_info->port = atoi(tds_dstr_cstr(&value));
		} else if (strcasecmp(option, "TDS_Version") == 0) {
			tds_config_verstr(tds_dstr_cstr(&value), connect_info);
		} else if (strcasecmp(option, "Domain") == 0) {
			dest_s = &connect_info->default_domain;
		} else if (strcasecmp(option, "TextSize") == 0) {
			connect_info->text_size = atoi(tds_dstr_cstr(&value));
		} else if (strcasecmp(option, "PacketSize") == 0) {
			connect_info->block_size = atoi(tds_dstr_cstr(&value));
			/* TODO "Address" field */
		}

		/* copy to destination */
		if (dest_s) {
			tds_dstr_set(dest_s, tds_dstr_cstr(&value));
			tds_dstr_init(&value);
		}

		p = end;
		/* handle "" ";.." "};.." cases */
		if (p >= connect_string_end)
			break;
		if (*p == '}')
			++p;
		++p;
	}

	tds_dstr_free(&value);
	return p != NULL;
}
Exemple #4
0
DSTR*
tds_dstr_dup(DSTR * s, const DSTR * src)
{
	return tds_dstr_copyn(s, src->dstr_s, src->dstr_size);
}
Exemple #5
0
/**
 * copy a string from another
 * @param s      dynamic string
 * @param src    source buffer
 * @return string copied or NULL on memory error
 */
DSTR*
tds_dstr_copy(DSTR * s, const char *src)
{
	return tds_dstr_copyn(s, src, strlen(src));
}
/** 
 * Parse connection string and fill login according
 * @param connect_string     connect string
 * @param connect_string_end connect string end (pointer to char past last)
 * @param login         where to store connection info
 * @return 1 if success 0 otherwhise
 */
int
odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSLOGIN * login,
			  TDS_PARSED_PARAM *parsed_params)
{
	const char *p, *end;
	DSTR *dest_s, value = DSTR_INITIALIZER;
	enum { CFG_DSN = 1, CFG_SERVER = 2, CFG_SERVERNAME = 4 };
	unsigned int cfgs = 0;	/* flags for indicate second parse of string */
	char option[24];
	int trusted = 0;

	if (parsed_params)
		memset(parsed_params, 0, sizeof(*parsed_params)*ODBC_PARAM_SIZE);

	for (p = connect_string; p < connect_string_end && *p;) {
		int num_param = -1;

		dest_s = NULL;

		/* handle empty options */
		while (p < connect_string_end && *p == ';')
			++p;

		/* parse option */
		end = (const char *) memchr(p, '=', connect_string_end - p);
		if (!end)
			break;

		/* account for spaces between ;'s. */
		while (p < end && *p == ' ')
			++p;

		if ((end - p) >= (int) sizeof(option))
			option[0] = 0;
		else {
			memcpy(option, p, end - p);
			option[end - p] = 0;
		}

		/* parse value */
		p = end + 1;
		if (*p == '{') {
			++p;
			/* search "};" */
			end = p;
			while ((end = (const char *) memchr(end, '}', connect_string_end - end)) != NULL) {
				if ((end + 1) != connect_string_end && end[1] == ';')
					break;
				++end;
			}
		} else {
			end = (const char *) memchr(p, ';', connect_string_end - p);
		}
		if (!end)
			end = connect_string_end;

		if (!tds_dstr_copyn(&value, p, end - p)) {
			odbc_errs_add(errs, "HY001", NULL);
			return 0;
		}

#define CHK_PARAM(p) (strcasecmp(option, odbc_param_##p) == 0 && (num_param=ODBC_PARAM_##p) >= 0)
		if (CHK_PARAM(Server)) {
			/* error if servername or DSN specified */
			if ((cfgs & (CFG_DSN|CFG_SERVERNAME)) != 0) {
				tds_dstr_free(&value);
				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
				return 0;
			}
			if (!cfgs) {
				dest_s = &login->server_name;
				/* not that safe cast but works -- freddy77 */
				if (!parse_server(errs, (char *) tds_dstr_cstr(&value), login)) {
					tds_dstr_free(&value);
					return 0;
				}
				cfgs = CFG_SERVER;
			}
		} else if (CHK_PARAM(Servername)) {
			if ((cfgs & (CFG_DSN|CFG_SERVER)) != 0) {
				tds_dstr_free(&value);
				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
				return 0;
			}
			if (!cfgs) {
				odbc_dstr_swap(&login->server_name, &value);
				tds_read_conf_file(login, tds_dstr_cstr(&login->server_name));
				cfgs = CFG_SERVERNAME;
				p = connect_string;
				continue;
			}
		} else if (CHK_PARAM(DSN)) {
			if ((cfgs & (CFG_SERVER|CFG_SERVERNAME)) != 0) {
				tds_dstr_free(&value);
				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
				return 0;
			}
			if (!cfgs) {
				if (!odbc_get_dsn_info(errs, tds_dstr_cstr(&value), login)) {
					tds_dstr_free(&value);
					return 0;
				}
				cfgs = CFG_DSN;
				p = connect_string;
				continue;
			}
		} else if (CHK_PARAM(Database)) {
			dest_s = &login->database;
		} else if (CHK_PARAM(UID)) {
			dest_s = &login->user_name;
		} else if (CHK_PARAM(PWD)) {
			dest_s = &login->password;
		} else if (CHK_PARAM(APP)) {
			dest_s = &login->app_name;
		} else if (CHK_PARAM(WSID)) {
			dest_s = &login->client_host_name;
		} else if (CHK_PARAM(Language)) {
			tds_parse_conf_section(TDS_STR_LANGUAGE, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(Port)) {
			tds_parse_conf_section(TDS_STR_PORT, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(TDS_Version)) {
			tds_parse_conf_section(TDS_STR_VERSION, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(TextSize)) {
			tds_parse_conf_section(TDS_STR_TEXTSZ, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(PacketSize)) {
			tds_parse_conf_section(TDS_STR_BLKSZ, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(ClientCharset)) {
			tds_parse_conf_section(TDS_STR_CLCHARSET, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(DumpFile)) {
			tds_parse_conf_section(TDS_STR_DUMPFILE, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(DumpFileAppend)) {
			tds_parse_conf_section(TDS_STR_APPENDMODE, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(DebugFlags)) {
			tds_parse_conf_section(TDS_STR_DEBUGFLAGS, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(Encryption)) {
			tds_parse_conf_section(TDS_STR_ENCRYPTION, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(UseNTLMv2)) {
			tds_parse_conf_section(TDS_STR_USENTLMV2, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(REALM)) {
			tds_parse_conf_section(TDS_STR_REALM, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(ServerSPN)) {
			tds_parse_conf_section(TDS_STR_SPN, tds_dstr_cstr(&value), login);
		} else if (CHK_PARAM(Trusted_Connection)) {
			trusted = tds_config_boolean(option, tds_dstr_cstr(&value), login);
			tdsdump_log(TDS_DBG_INFO1, "trusted %s -> %d\n", tds_dstr_cstr(&value), trusted);
			num_param = -1;
			/* TODO odbc_param_Address field */
		} else if (CHK_PARAM(MARS_Connection)) {
			if (tds_config_boolean(option, tds_dstr_cstr(&value), login))
				login->mars = 1;
		} else if (CHK_PARAM(AttachDbFilename)) {
			dest_s = &login->db_filename;
		} else if (CHK_PARAM(ApplicationIntent)) {
			const char *readonly_intent;

			if (strcasecmp(tds_dstr_cstr(&value), "ReadOnly") == 0) {
				readonly_intent = "yes";
			} else if (strcasecmp(tds_dstr_cstr(&value), "ReadWrite") == 0) {
				readonly_intent = "no";
			} else {
				tdsdump_log(TDS_DBG_ERROR, "Invalid ApplicationIntent %s\n", tds_dstr_cstr(&value));
				return 0;
			}

			tds_parse_conf_section(TDS_STR_READONLY_INTENT, readonly_intent, login);
			tdsdump_log(TDS_DBG_INFO1, "Application Intent %s\n", readonly_intent);
		}

		if (num_param >= 0 && parsed_params) {
			parsed_params[num_param].p = p;
			parsed_params[num_param].len = end - p;
		}

		/* copy to destination */
		if (dest_s)
			odbc_dstr_swap(dest_s, &value);

		p = end;
		/* handle "" ";.." "};.." cases */
		if (p >= connect_string_end)
			break;
		if (*p == '}')
			++p;
		++p;
	}

	if (trusted) {
		if (parsed_params) {
			parsed_params[ODBC_PARAM_Trusted_Connection].p = "Yes";
			parsed_params[ODBC_PARAM_Trusted_Connection].len = 3;
			parsed_params[ODBC_PARAM_UID].p = NULL;
			parsed_params[ODBC_PARAM_PWD].p = NULL;
		}
		tds_dstr_empty(&login->user_name);
		tds_dstr_empty(&login->password);
	}

	tds_dstr_free(&value);
	return 1;
}