summaryrefslogtreecommitdiff
path: root/libmysqld/lib_sql.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2010-03-29 17:13:53 +0200
committerSergei Golubchik <sergii@pisem.net>2010-03-29 17:13:53 +0200
commit291fd9698340f3d83ff096542720f7335cb078d2 (patch)
tree1e727dd05959dfa20ecc93fc8a4f8050ead61689 /libmysqld/lib_sql.cc
parent3e13f97bd4aaba25af5558512f933036c952494c (diff)
downloadmariadb-git-291fd9698340f3d83ff096542720f7335cb078d2.tar.gz
pluggable auth with plugin examples
Makefile.am: add new API files to the check_abi rule, remove duplicates client/CMakeLists.txt: now a client can use dlopen too client/Makefile.am: be csh-friendly include/my_global.h: add dummy plugs for dlopen and co. for the code that needs them to work in static builds mysys/Makefile.am: be csh-friendly plugin/auth/dialog.c: typo fixed
Diffstat (limited to 'libmysqld/lib_sql.cc')
-rw-r--r--libmysqld/lib_sql.cc79
1 files changed, 46 insertions, 33 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 7de1ecd6ef3..5521e024f8f 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -35,7 +35,6 @@ C_MODE_START
#include <mysql.h>
#undef ER
#include "errmsg.h"
-#include <sql_common.h>
#include "embedded_priv.h"
extern unsigned int mysql_server_last_errno;
@@ -413,11 +412,10 @@ static MYSQL_RES * emb_store_result(MYSQL *mysql)
return mysql_store_result(mysql);
}
-int emb_read_change_user_result(MYSQL *mysql,
- char *buff __attribute__((unused)),
- const char *passwd __attribute__((unused)))
+int emb_read_change_user_result(MYSQL *mysql)
{
- return mysql_errno(mysql);
+ mysql->net.read_pos= (uchar*)""; // fake an OK packet
+ return mysql_errno(mysql) ? packet_error : 1 /* length of the OK packet */;
}
MYSQL_METHODS embedded_methods=
@@ -428,6 +426,7 @@ MYSQL_METHODS embedded_methods=
emb_store_result,
emb_fetch_lengths,
emb_flush_use_result,
+ emb_read_change_user_result,
emb_list_fields,
emb_read_prepare_result,
emb_stmt_execute,
@@ -436,7 +435,6 @@ MYSQL_METHODS embedded_methods=
emb_free_embedded_thd,
emb_read_statistics,
emb_read_query_result,
- emb_read_change_user_result,
emb_read_rows_from_cursor
};
@@ -584,6 +582,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag)
THD *thd = (THD *)mysql->thd;
thd->mysql= mysql;
mysql->server_version= server_version;
+ mysql->client_flag= client_flag;
init_alloc_root(&mysql->field_alloc, 8192, 0);
}
@@ -648,14 +647,19 @@ err:
int check_embedded_connection(MYSQL *mysql, const char *db)
{
int result;
+ LEX_STRING db_str = { (char*)db, db ? strlen(db) : 0 };
THD *thd= (THD*)mysql->thd;
thd_init_client_charset(thd, mysql->charset->number);
thd->update_charset();
Security_context *sctx= thd->security_ctx;
sctx->host_or_ip= sctx->host= (char*) my_localhost;
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
- sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
- result= check_user(thd, COM_CONNECT, NULL, 0, db, true);
+ strmake(sctx->priv_user, mysql->user, USERNAME_LENGTH-1);
+ sctx->user= my_strdup(mysql->user, MYF(0));
+ sctx->master_access= GLOBAL_ACLS; // Full rights
+ /* Change database if necessary */
+ if (!(result= (db && db[0] && mysql_change_db(thd, &db_str, FALSE))))
+ my_ok(thd);
net_end_statement(thd);
emb_read_query_result(mysql);
return result;
@@ -664,14 +668,15 @@ int check_embedded_connection(MYSQL *mysql, const char *db)
#else
int check_embedded_connection(MYSQL *mysql, const char *db)
{
+ /*
+ we emulate a COM_CHANGE_USER user here,
+ it's easier than to emulate the complete 3-way handshake
+ */
+ char buf[USERNAME_LENGTH + SCRAMBLE_LENGTH + 1 + 2*NAME_LEN + 2], *end;
+ NET *net= &mysql->net;
THD *thd= (THD*)mysql->thd;
Security_context *sctx= thd->security_ctx;
- int result;
- char scramble_buff[SCRAMBLE_LENGTH];
- int passwd_len;
- thd_init_client_charset(thd, mysql->charset->number);
- thd->update_charset();
if (mysql->options.client_ip)
{
sctx->host= my_strdup(mysql->options.client_ip, MYF(0));
@@ -682,36 +687,44 @@ int check_embedded_connection(MYSQL *mysql, const char *db)
sctx->host_or_ip= sctx->host;
if (acl_check_host(sctx->host, sctx->ip))
- {
- result= ER_HOST_NOT_PRIVILEGED;
goto err;
- }
- sctx->user= my_strdup(mysql->user, MYF(0));
+ /* construct a COM_CHANGE_USER packet */
+ end= strmake(buf, mysql->user, USERNAME_LENGTH) + 1;
+
+ memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
+ thd->scramble[SCRAMBLE_LENGTH]= 0;
+
if (mysql->passwd && mysql->passwd[0])
{
- memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
- thd->scramble[SCRAMBLE_LENGTH]= 0;
- scramble(scramble_buff, thd->scramble, mysql->passwd);
- passwd_len= SCRAMBLE_LENGTH;
+ *end++= SCRAMBLE_LENGTH;
+ scramble(end, thd->scramble, mysql->passwd);
+ end+= SCRAMBLE_LENGTH;
}
else
- passwd_len= 0;
+ *end++= 0;
- if((result= check_user(thd, COM_CONNECT,
- scramble_buff, passwd_len, db, true)))
- goto err;
+ end= strmake(end, db ? db : "", NAME_LEN) + 1;
- return 0;
-err:
+ int2store(end, (ushort) mysql->charset->number);
+ end+= 2;
+
+ /* acl_authenticate() takes the data from thd->net->read_pos */
+ thd->net.read_pos= (uchar*)buf;
+
+ if (acl_authenticate(thd, 0, end - buf))
{
- NET *net= &mysql->net;
- strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1);
- memcpy(net->sqlstate,
- mysql_errno_to_sqlstate(thd->main_da.sql_errno()),
- sizeof(net->sqlstate)-1);
+ x_free(thd->security_ctx->user);
+ goto err;
}
- return result;
+ return 0;
+
+err:
+ strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1);
+ memcpy(net->sqlstate,
+ mysql_errno_to_sqlstate(thd->main_da.sql_errno()),
+ sizeof(net->sqlstate)-1);
+ return 1;
}
#endif