diff options
author | Sergei Golubchik <sergii@pisem.net> | 2010-03-29 17:13:53 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2010-03-29 17:13:53 +0200 |
commit | 291fd9698340f3d83ff096542720f7335cb078d2 (patch) | |
tree | 1e727dd05959dfa20ecc93fc8a4f8050ead61689 /libmysqld/lib_sql.cc | |
parent | 3e13f97bd4aaba25af5558512f933036c952494c (diff) | |
download | mariadb-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.cc | 79 |
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 |