Mysql源码学习――用户认证原理与实现(三)

2014-11-24 10:35:16 · 作者: · 浏览: 3

{

...

}

vio_keepalive(net->vio, TRUE);

...

char *user= end;

char *passwd= strend(user)+1;

uint user_len= passwd - user - 1;

char *db= passwd;

char db_buff[NAME_LEN + 1]; // buffer to store db in utf8

char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8

uint dummy_errors;

uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION

(uchar)(*passwd++) : strlen(passwd);

db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB

db + passwd_len + 1 : 0;

uint db_len= db strlen(db) : 0;

if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)

{

inc_host_errors(&thd->remote.sin_addr);

my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);

return 1;

}

...

/* If username starts and ends in "'", chop them off */

if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')

{

user[user_len-1]= 0;

user++;

user_len-= 2;

}

if (thd->main_security_ctx.user)

x_free(thd->main_security_ctx.user);

if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))

return 1; /* The error is set by my_strdup(). */

return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);//验证用户名和密码

}

  

上面的源码主要做了如下几件事情:

获取客户端的IP和主机名

acl_check_host函数验证USER表中是否存在相应的IP或HOST,如果不存在直接报错

获取用户名和密码

check_user函数验证用户名和密码(不输入用户名默认为ODBC),如果系统表中不存在匹配的报错返回

获取用户的权限列表,验证用户的相关属性是否合法,如连接数是否超过上限,连接是否超时,操作是否超过限制等信息,如果不合法,则报错返回。

由于在一个认证的过程中涉及到的东西比较多,各个方面吧,我不能一一跟踪,只能大概了解其中的实现流程,捡重点进行

跟踪,有兴趣的童鞋自己具体跟踪吧

题外话:

Mysql中权限系统表都是在系统启动时,载入内存的(当然User表也是这样),一般情况下,不需要进行频繁的授权和回收

操作,这中情况下,权限表基本保持不变,将其在系统启动的时候载入内存的好处自然是快速的进行权限判断,减少磁盘的I/O,

你懂的^_^。有好处自然有坏处,就是在频繁进行授权和回收相关操作时,权限表需要重新载入内存,Mysql为了避免这种情况,

在手册中已经说的很清楚了,授权和回收只会反应到磁盘中,内存的数据字典信息是不会改变的,如果想立即生效,需要调用

FLUSH PRIVILEGES系统函数,这个系统函数的工作应该就是对权限系统表的RELOAD。

下篇进入实质性的介绍,通过跟踪一个建表语句,来学习Mysql是如何存储表的元数据的,即frm格式文件的剖析。

<script>

PS.最近工作比较清闲,却迷失了方向,一会想看OS的实现,一会想看逆向,一会又想看计算机组成原理,哎,转专业的学生伤

不起啊,计算机很神奇,我很迷茫…

摘自 心中无码