diff --git a/redis.conf b/redis.conf index 0836a3d..cb557d1 100644 --- a/redis.conf +++ b/redis.conf @@ -759,7 +759,7 @@ acllog-max-len 128 # The format of the external ACL user file is exactly the same as the # format that is used inside redis.conf to describe users. # -# aclfile /etc/redis/users.acl +aclfile /tmp/users.acl # IMPORTANT NOTE: starting with Redis 6 "requirepass" is just a compatiblity # layer on top of the new ACL system. The option effect will be just setting diff --git a/src/acl.c b/src/acl.c index 6dd0f70..fb83902 100644 --- a/src/acl.c +++ b/src/acl.c @@ -148,7 +148,9 @@ int time_independent_strcmp(char *a, char *b) { } /* Given an SDS string, returns the SHA256 hex representation as a - * new SDS string. */ + * new SDS string. + * 对密码进行加密 + * * */ sds ACLHashPassword(unsigned char *cleartext, size_t len) { SHA256_CTX ctx; unsigned char hash[SHA256_BLOCK_SIZE]; @@ -232,7 +234,10 @@ void *ACLListDupSds(void *item) { * of users (the Users global radix tree), and returns a reference to * the structure representing the user. * - * If the user with such name already exists NULL is returned. */ + * If the user with such name already exists NULL is returned. + * + * 创建用户 + * */ user *ACLCreateUser(const char *name, size_t namelen) { if (raxFind(Users,(unsigned char*)name,namelen) != raxNotFound) return NULL; user *u = zmalloc(sizeof(*u)); @@ -255,7 +260,9 @@ user *ACLCreateUser(const char *name, size_t namelen) { /* This function should be called when we need an unlinked "fake" user * we can use in order to validate ACL rules or for other similar reasons. * The user will not get linked to the Users radix tree. The returned - * user should be released with ACLFreeUser() as usually. */ + * user should be released with ACLFreeUser() as usually. + * + * * */ user *ACLCreateUnlinkedUser(void) { char username[64]; for (int j = 0; ; j++) { @@ -354,9 +361,13 @@ int ACLGetCommandBitCoordinates(uint64_t id, uint64_t *word, uint64_t *bit) { * but just the lowlevel bitmask. * * If the bit overflows the user internal representation, zero is returned - * in order to disallow the execution of the command in such edge case. */ + * in order to disallow the execution of the command in such edge case. + * + * 通过计算command对应的bit位,计算是否存在权限 + * * */ int ACLGetUserCommandBit(user *u, unsigned long id) { uint64_t word, bit; + // 计算命令在allowed_commands当中对应的bit位 if (ACLGetCommandBitCoordinates(id,&word,&bit) == C_ERR) return 0; return (u->allowed_commands[word] & bit) != 0; } @@ -927,18 +938,22 @@ char *ACLSetUserStringError(void) { } /* Initialize the default user, that will always exist for all the process - * lifetime. */ + * lifetime. + * 初始化默认用户 + * */ void ACLInitDefaultUser(void) { DefaultUser = ACLCreateUser("default",7); - ACLSetUser(DefaultUser,"+@all",-1); - ACLSetUser(DefaultUser,"~*",-1); - ACLSetUser(DefaultUser,"on",-1); - ACLSetUser(DefaultUser,"nopass",-1); + ACLSetUser(DefaultUser,"+@all",-1); // 默认用户赋予所有命令的权限 + ACLSetUser(DefaultUser,"~*",-1); // 可以操作任何key + ACLSetUser(DefaultUser,"on",-1); // 默认开启 + ACLSetUser(DefaultUser,"nopass",-1);// 默认不需要密码 } -/* Initialization of the ACL subsystem. */ +/* Initialization of the ACL subsystem. + * 初始化ACL子系统 + * */ void ACLInit(void) { - Users = raxNew(); + Users = raxNew(); // 初始化用户信息 UsersToLoad = listCreate(); ACLLog = listCreate(); ACLInitDefaultUser(); @@ -1056,7 +1071,9 @@ user *ACLGetUserByName(const char *name, size_t namelen) { * ACL_DENIED_CMD or ACL_DENIED_KEY is returned: the first in case the * command cannot be executed because the user is not allowed to run such * command, the second if the command is denied because the user is trying - * to access keys that are not among the specified patterns. */ + * to access keys that are not among the specified patterns. + * 检查当前用户是否拥有对当前命令的权限 + * * */ int ACLCheckCommandPerm(client *c, int *keyidxptr) { user *u = c->user; uint64_t id = c->cmd->id; @@ -1069,7 +1086,9 @@ int ACLCheckCommandPerm(client *c, int *keyidxptr) { c->cmd->proc != authCommand) { /* If the bit is not set we have to check further, in case the - * command is allowed just with that specific subcommand. */ + * command is allowed just with that specific subcommand. + * + * */ if (ACLGetUserCommandBit(u,id) == 0) { /* Check if the subcommand matches. */ if (c->argc < 2 || @@ -1151,7 +1170,9 @@ int ACLCheckCommandPerm(client *c, int *keyidxptr) { * * When an error is detected and C_ERR is returned, the function populates * by reference (if not set to NULL) the argc_err argument with the index - * of the argv vector that caused the error. */ + * of the argv vector that caused the error. + * 加载user配置的ACL信息 + * * * */ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { if (argc < 2 || strcasecmp(argv[0],"user")) { if (argc_err) *argc_err = 0; @@ -1183,7 +1204,9 @@ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { /* This function will load the configured users appended to the server * configuration via ACLAppendUserForLoading(). On loading errors it will - * log an error and return C_ERR, otherwise C_OK will be returned. */ + * log an error and return C_ERR, otherwise C_OK will be returned. + * 从user配置项中读取ACl信息 + * * */ int ACLLoadConfiguredUsers(void) { listIter li; listNode *ln; @@ -1192,11 +1215,12 @@ int ACLLoadConfiguredUsers(void) { sds *aclrules = listNodeValue(ln); sds username = aclrules[0]; + // 检查ACL用户名当中是否存在空格 if (ACLStringHasSpaces(aclrules[0],sdslen(aclrules[0]))) { serverLog(LL_WARNING,"Spaces not allowed in ACL usernames"); return C_ERR; } - + // 创建ACL用户 user *u = ACLCreateUser(username,sdslen(username)); if (!u) { u = ACLGetUserByName(username,sdslen(username)); @@ -1206,6 +1230,7 @@ int ACLLoadConfiguredUsers(void) { /* Load every rule defined for this user. */ for (int j = 1; aclrules[j]; j++) { + // 添加当前用户的所有属性 if (ACLSetUser(u,aclrules[j],sdslen(aclrules[j])) != C_OK) { char *errmsg = ACLSetUserStringError(); serverLog(LL_WARNING,"Error loading ACL rule '%s' for " @@ -1216,7 +1241,9 @@ int ACLLoadConfiguredUsers(void) { } /* Having a disabled user in the configuration may be an error, - * warn about it without returning any error to the caller. */ + * warn about it without returning any error to the caller. + * 用户没有开启的时候打印到日志里面 + * */ if (u->flags & USER_FLAG_DISABLED) { serverLog(LL_NOTICE, "The user '%s' is disabled (there is no " "'on' modifier in the user description). Make " @@ -1249,7 +1276,10 @@ int ACLLoadConfiguredUsers(void) { * * At the end of the process, if no errors were found in the whole file then * NULL is returned. Otherwise an SDS string describing in a single line - * a description of all the issues found is returned. */ + * a description of all the issues found is returned. + * + * 从aclfile配置的文件里面读取ACL信息 + * */ sds ACLLoadFromFile(const char *filename) { FILE *fp; char buf[1024]; @@ -1466,7 +1496,9 @@ cleanup: * loaded, and we are ready to start, in order to load the ACLs either from * the pending list of users defined in redis.conf, or from the ACL file. * The function will just exit with an error if the user is trying to mix - * both the loading methods. */ + * both the loading methods. + * 加载redis.conf配置项aclfile对应文件里面的ACL权限信息 + * */ void ACLLoadUsersAtStartup(void) { if (server.acl_filename[0] != '\0' && listLength(UsersToLoad) != 0) { serverLog(LL_WARNING, @@ -1477,7 +1509,7 @@ void ACLLoadUsersAtStartup(void) { "directly in your redis.conf, but not both."); exit(1); } - + // 加载user配置的ACL信息 if (ACLLoadConfiguredUsers() == C_ERR) { serverLog(LL_WARNING, "Critical error while loading ACLs. Exiting."); diff --git a/src/networking.c b/src/networking.c index 778c11c..21566e7 100644 --- a/src/networking.c +++ b/src/networking.c @@ -1872,7 +1872,9 @@ void processInputBuffer(client *c) { break; } - /* We are finally ready to execute the command. */ + /* We are finally ready to execute the command. + * 真正执行代码的函数 + * */ if (processCommandAndResetClient(c) == C_ERR) { /* If the client is no longer valid, we avoid exiting this * loop and trimming the client buffer later. So we return diff --git a/src/server.c b/src/server.c index e6b634c..5e223df 100644 --- a/src/server.c +++ b/src/server.c @@ -3418,7 +3418,9 @@ int processCommand(client *c) { /* The QUIT command is handled separately. Normal command procs will * go through checking for replication and QUIT will cause trouble * when FORCE_REPLICATION is enabled and would be implemented in - * a regular command proc. */ + * a regular command proc. + * 首先處理quit命令 + * * */ if (!strcasecmp(c->argv[0]->ptr,"quit")) { addReply(c,shared.ok); c->flags |= CLIENT_CLOSE_AFTER_REPLY; diff --git a/src/server.h b/src/server.h index 7191aef..0f3f4d7 100644 --- a/src/server.h +++ b/src/server.h @@ -153,7 +153,7 @@ typedef long long ustime_t; /* microsecond time type. */ /* Hash table parameters */ #define HASHTABLE_MIN_FILL 10 /* Minimal hash table fill 10% */ -/* Command flags. Please check the command table defined in the redis.c file +/* Command flags. Please check the command table defined in the server.c file * for more information about the meaning of every flag. */ #define CMD_WRITE (1ULL<<0) /* "write" flag */ #define CMD_READONLY (1ULL<<1) /* "read-only" flag */ @@ -721,7 +721,9 @@ typedef struct readyList { /* This structure represents a Redis user. This is useful for ACLs, the * user is associated to the connection after the connection is authenticated. - * If there is no associated user, the connection uses the default user. */ + * If there is no associated user, the connection uses the default user. + * 表示Redis ACL所有的用户不能超过1024个 + * */ #define USER_COMMAND_BITS_COUNT 1024 /* The total number of command bits in the user structure. The last valid command ID we can set in the user @@ -736,6 +738,7 @@ typedef struct readyList { no AUTH is needed, and every connection is immediately authenticated. */ +/* 用户信息 */ typedef struct { sds name; /* The username as an SDS string. */ uint64_t flags; /* See USER_FLAG_* */ @@ -746,7 +749,9 @@ typedef struct { * * If the bit for a given command is NOT set and the command has * subcommands, Redis will also check allowed_subcommands in order to - * understand if the command can be executed. */ + * understand if the command can be executed. + * + * */ uint64_t allowed_commands[USER_COMMAND_BITS_COUNT/64]; /* This array points, for each command ID (corresponding to the command @@ -1428,7 +1433,7 @@ struct redisServer { long long latency_monitor_threshold; dict *latency_events; /* ACLs */ - char *acl_filename; /* ACL Users file. NULL if not configured. */ + char *acl_filename; /* ACL Users file. NULL if not configured.ACL文件路径,需要配置已经存在的文件,否则会报错启动失败 */ unsigned long acllog_max_len; /* Maximum length of the ACL LOG list. */ sds requirepass; /* Remember the cleartext password set with the old "requirepass" directive for backward