433 lines
19 KiB
Diff
433 lines
19 KiB
Diff
diff -uNr redis-6.0.1/src/acl.c redis-6.0.1.mod/src/acl.c
|
|
--- redis-6.0.1/src/acl.c 2020-05-02 01:10:20.000000000 +0300
|
|
+++ redis-6.0.1.mod/src/acl.c 2020-05-13 13:06:20.789831765 +0300
|
|
@@ -38,7 +38,7 @@
|
|
|
|
rax *Users; /* Table mapping usernames to user structures. */
|
|
|
|
-user *DefaultUser; /* Global reference to the default user.
|
|
+rduser *DefaultUser; /* Global reference to the default user.
|
|
Every new connection is associated to it, if no
|
|
AUTH or HELLO is used to authenticate with a
|
|
different user. */
|
|
@@ -93,9 +93,9 @@
|
|
{NULL,0} /* Terminator. */
|
|
};
|
|
|
|
-void ACLResetSubcommandsForCommand(user *u, unsigned long id);
|
|
-void ACLResetSubcommands(user *u);
|
|
-void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub);
|
|
+void ACLResetSubcommandsForCommand(rduser *u, unsigned long id);
|
|
+void ACLResetSubcommands(rduser *u);
|
|
+void ACLAddAllowedSubcommand(rduser *u, unsigned long id, const char *sub);
|
|
void ACLFreeLogEntry(void *le);
|
|
|
|
/* The length of the string representation of a hashed password. */
|
|
@@ -214,9 +214,9 @@
|
|
* the structure representing the user.
|
|
*
|
|
* If the user with such name already exists NULL is returned. */
|
|
-user *ACLCreateUser(const char *name, size_t namelen) {
|
|
+rduser *ACLCreateUser(const char *name, size_t namelen) {
|
|
if (raxFind(Users,(unsigned char*)name,namelen) != raxNotFound) return NULL;
|
|
- user *u = zmalloc(sizeof(*u));
|
|
+ rduser *u = zmalloc(sizeof(*u));
|
|
u->name = sdsnewlen(name,namelen);
|
|
u->flags = USER_FLAG_DISABLED;
|
|
u->allowed_subcommands = NULL;
|
|
@@ -237,11 +237,11 @@
|
|
* 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 *ACLCreateUnlinkedUser(void) {
|
|
+rduser *ACLCreateUnlinkedUser(void) {
|
|
char username[64];
|
|
for (int j = 0; ; j++) {
|
|
snprintf(username,sizeof(username),"__fakeuser:%d__",j);
|
|
- user *fakeuser = ACLCreateUser(username,strlen(username));
|
|
+ rduser *fakeuser = ACLCreateUser(username,strlen(username));
|
|
if (fakeuser == NULL) continue;
|
|
int retval = raxRemove(Users,(unsigned char*) username,
|
|
strlen(username),NULL);
|
|
@@ -252,7 +252,7 @@
|
|
|
|
/* Release the memory used by the user structure. Note that this function
|
|
* will not remove the user from the Users global radix tree. */
|
|
-void ACLFreeUser(user *u) {
|
|
+void ACLFreeUser(rduser *u) {
|
|
sdsfree(u->name);
|
|
listRelease(u->passwords);
|
|
listRelease(u->patterns);
|
|
@@ -263,7 +263,7 @@
|
|
/* When a user is deleted we need to cycle the active
|
|
* connections in order to kill all the pending ones that
|
|
* are authenticated with such user. */
|
|
-void ACLFreeUserAndKillClients(user *u) {
|
|
+void ACLFreeUserAndKillClients(rduser *u) {
|
|
listIter li;
|
|
listNode *ln;
|
|
listRewind(server.clients,&li);
|
|
@@ -287,7 +287,7 @@
|
|
/* Copy the user ACL rules from the source user 'src' to the destination
|
|
* user 'dst' so that at the end of the process they'll have exactly the
|
|
* same rules (but the names will continue to be the original ones). */
|
|
-void ACLCopyUser(user *dst, user *src) {
|
|
+void ACLCopyUser(rduser *dst, rduser *src) {
|
|
listRelease(dst->passwords);
|
|
listRelease(dst->patterns);
|
|
dst->passwords = listDup(src->passwords);
|
|
@@ -336,7 +336,7 @@
|
|
*
|
|
* If the bit overflows the user internal representation, zero is returned
|
|
* in order to disallow the execution of the command in such edge case. */
|
|
-int ACLGetUserCommandBit(user *u, unsigned long id) {
|
|
+int ACLGetUserCommandBit(rduser *u, unsigned long id) {
|
|
uint64_t word, bit;
|
|
if (ACLGetCommandBitCoordinates(id,&word,&bit) == C_ERR) return 0;
|
|
return (u->allowed_commands[word] & bit) != 0;
|
|
@@ -345,7 +345,7 @@
|
|
/* When +@all or allcommands is given, we set a reserved bit as well that we
|
|
* can later test, to see if the user has the right to execute "future commands",
|
|
* that is, commands loaded later via modules. */
|
|
-int ACLUserCanExecuteFutureCommands(user *u) {
|
|
+int ACLUserCanExecuteFutureCommands(rduser *u) {
|
|
return ACLGetUserCommandBit(u,USER_COMMAND_BITS_COUNT-1);
|
|
}
|
|
|
|
@@ -354,7 +354,7 @@
|
|
* is performed. As a side effect of calling this function with a value of
|
|
* zero, the user flag ALLCOMMANDS is cleared since it is no longer possible
|
|
* to skip the command bit explicit test. */
|
|
-void ACLSetUserCommandBit(user *u, unsigned long id, int value) {
|
|
+void ACLSetUserCommandBit(rduser *u, unsigned long id, int value) {
|
|
uint64_t word, bit;
|
|
if (value == 0) u->flags &= ~USER_FLAG_ALLCOMMANDS;
|
|
if (ACLGetCommandBitCoordinates(id,&word,&bit) == C_ERR) return;
|
|
@@ -370,7 +370,7 @@
|
|
* value. Since the category passed by the user may be non existing, the
|
|
* function returns C_ERR if the category was not found, or C_OK if it was
|
|
* found and the operation was performed. */
|
|
-int ACLSetUserCommandBitsForCategory(user *u, const char *category, int value) {
|
|
+int ACLSetUserCommandBitsForCategory(rduser *u, const char *category, int value) {
|
|
uint64_t cflag = ACLGetCommandCategoryFlagByName(category);
|
|
if (!cflag) return C_ERR;
|
|
dictIterator *di = dictGetIterator(server.orig_commands);
|
|
@@ -391,7 +391,7 @@
|
|
* in the subset of commands flagged with the specified category name.
|
|
* If the category name is not valid, C_ERR is returned, otherwise C_OK is
|
|
* returned and on and off are populated by reference. */
|
|
-int ACLCountCategoryBitsForUser(user *u, unsigned long *on, unsigned long *off,
|
|
+int ACLCountCategoryBitsForUser(rduser *u, unsigned long *on, unsigned long *off,
|
|
const char *category)
|
|
{
|
|
uint64_t cflag = ACLGetCommandCategoryFlagByName(category);
|
|
@@ -420,7 +420,7 @@
|
|
* as on/off, passwords and so forth. The returned string always starts with
|
|
* the +@all or -@all rule, depending on the user bitmap, and is followed, if
|
|
* needed, by the other rules needed to narrow or extend what the user can do. */
|
|
-sds ACLDescribeUserCommandRules(user *u) {
|
|
+sds ACLDescribeUserCommandRules(rduser *u) {
|
|
sds rules = sdsempty();
|
|
int additive; /* If true we start from -@all and add, otherwise if
|
|
false we start from +@all and remove. */
|
|
@@ -428,8 +428,8 @@
|
|
/* This code is based on a trick: as we generate the rules, we apply
|
|
* them to a fake user, so that as we go we still know what are the
|
|
* bit differences we should try to address by emitting more rules. */
|
|
- user fu = {0};
|
|
- user *fakeuser = &fu;
|
|
+ rduser fu = {0};
|
|
+ rduser *fakeuser = &fu;
|
|
|
|
/* Here we want to understand if we should start with +@all and remove
|
|
* the commands corresponding to the bits that are not set in the user
|
|
@@ -520,7 +520,7 @@
|
|
* the ACLDescribeUserCommandRules() function. This is the function we call
|
|
* when we want to rewrite the configuration files describing ACLs and
|
|
* in order to show users with ACL LIST. */
|
|
-sds ACLDescribeUser(user *u) {
|
|
+sds ACLDescribeUser(rduser *u) {
|
|
sds res = sdsempty();
|
|
|
|
/* Flags. */
|
|
@@ -579,7 +579,7 @@
|
|
|
|
/* Flush the array of allowed subcommands for the specified user
|
|
* and command ID. */
|
|
-void ACLResetSubcommandsForCommand(user *u, unsigned long id) {
|
|
+void ACLResetSubcommandsForCommand(rduser *u, unsigned long id) {
|
|
if (u->allowed_subcommands && u->allowed_subcommands[id]) {
|
|
for (int i = 0; u->allowed_subcommands[id][i]; i++)
|
|
sdsfree(u->allowed_subcommands[id][i]);
|
|
@@ -591,7 +591,7 @@
|
|
/* Flush the entire table of subcommands. This is useful on +@all, -@all
|
|
* or similar to return back to the minimal memory usage (and checks to do)
|
|
* for the user. */
|
|
-void ACLResetSubcommands(user *u) {
|
|
+void ACLResetSubcommands(rduser *u) {
|
|
if (u->allowed_subcommands == NULL) return;
|
|
for (int j = 0; j < USER_COMMAND_BITS_COUNT; j++) {
|
|
if (u->allowed_subcommands[j]) {
|
|
@@ -607,7 +607,7 @@
|
|
|
|
/* Add a subcommand to the list of subcommands for the user 'u' and
|
|
* the command id specified. */
|
|
-void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub) {
|
|
+void ACLAddAllowedSubcommand(rduser *u, unsigned long id, const char *sub) {
|
|
/* If this is the first subcommand to be configured for
|
|
* this user, we have to allocate the subcommands array. */
|
|
if (u->allowed_subcommands == NULL) {
|
|
@@ -714,7 +714,7 @@
|
|
* ENODEV: The password you are trying to remove from the user does not exist.
|
|
* EBADMSG: The hash you are trying to add is not a valid hash.
|
|
*/
|
|
-int ACLSetUser(user *u, const char *op, ssize_t oplen) {
|
|
+int ACLSetUser(rduser *u, const char *op, ssize_t oplen) {
|
|
if (oplen == -1) oplen = strlen(op);
|
|
if (!strcasecmp(op,"on")) {
|
|
u->flags |= USER_FLAG_ENABLED;
|
|
@@ -943,7 +943,7 @@
|
|
* ENONENT: if the specified user does not exist at all.
|
|
*/
|
|
int ACLCheckUserCredentials(robj *username, robj *password) {
|
|
- user *u = ACLGetUserByName(username->ptr,sdslen(username->ptr));
|
|
+ rduser *u = ACLGetUserByName(username->ptr,sdslen(username->ptr));
|
|
if (u == NULL) {
|
|
errno = ENOENT;
|
|
return C_ERR;
|
|
@@ -1033,7 +1033,7 @@
|
|
}
|
|
|
|
/* Return an username by its name, or NULL if the user does not exist. */
|
|
-user *ACLGetUserByName(const char *name, size_t namelen) {
|
|
+rduser *ACLGetUserByName(const char *name, size_t namelen) {
|
|
void *myuser = raxFind(Users,(unsigned char*)name,namelen);
|
|
if (myuser == raxNotFound) return NULL;
|
|
return myuser;
|
|
@@ -1049,7 +1049,7 @@
|
|
* command, the second if the command is denied because the user is trying
|
|
* to access keys that are not among the specified patterns. */
|
|
int ACLCheckCommandPerm(client *c, int *keyidxptr) {
|
|
- user *u = c->user;
|
|
+ rduser *u = c->user;
|
|
uint64_t id = c->cmd->id;
|
|
|
|
/* If there is no associated user, the connection can run anything. */
|
|
@@ -1151,7 +1151,7 @@
|
|
|
|
/* Try to apply the user rules in a fake user to see if they
|
|
* are actually valid. */
|
|
- user *fakeuser = ACLCreateUnlinkedUser();
|
|
+ rduser *fakeuser = ACLCreateUnlinkedUser();
|
|
|
|
for (int j = 2; j < argc; j++) {
|
|
if (ACLSetUser(fakeuser,argv[j],sdslen(argv[j])) == C_ERR) {
|
|
@@ -1188,7 +1188,7 @@
|
|
return C_ERR;
|
|
}
|
|
|
|
- user *u = ACLCreateUser(username,sdslen(username));
|
|
+ rduser *u = ACLCreateUser(username,sdslen(username));
|
|
if (!u) {
|
|
u = ACLGetUserByName(username,sdslen(username));
|
|
serverAssert(u != NULL);
|
|
@@ -1267,13 +1267,13 @@
|
|
|
|
/* We need a fake user to validate the rules before making changes
|
|
* to the real user mentioned in the ACL line. */
|
|
- user *fakeuser = ACLCreateUnlinkedUser();
|
|
+ rduser *fakeuser = ACLCreateUnlinkedUser();
|
|
|
|
/* We do all the loading in a fresh instance of the Users radix tree,
|
|
* so if there are errors loading the ACL file we can rollback to the
|
|
* old version. */
|
|
rax *old_users = Users;
|
|
- user *old_default_user = DefaultUser;
|
|
+ rduser *old_default_user = DefaultUser;
|
|
Users = raxNew();
|
|
ACLInitDefaultUser();
|
|
|
|
@@ -1345,7 +1345,7 @@
|
|
|
|
/* We can finally lookup the user and apply the rule. If the
|
|
* user already exists we always reset it to start. */
|
|
- user *u = ACLCreateUser(argv[1],sdslen(argv[1]));
|
|
+ rduser *u = ACLCreateUser(argv[1],sdslen(argv[1]));
|
|
if (!u) {
|
|
u = ACLGetUserByName(argv[1],sdslen(argv[1]));
|
|
serverAssert(u != NULL);
|
|
@@ -1369,7 +1369,7 @@
|
|
/* The default user pointer is referenced in different places: instead
|
|
* of replacing such occurrences it is much simpler to copy the new
|
|
* default user configuration in the old one. */
|
|
- user *new = ACLGetUserByName("default",7);
|
|
+ rduser *new = ACLGetUserByName("default",7);
|
|
serverAssert(new != NULL);
|
|
ACLCopyUser(DefaultUser,new);
|
|
ACLFreeUser(new);
|
|
@@ -1401,7 +1401,7 @@
|
|
raxStart(&ri,Users);
|
|
raxSeek(&ri,"^",NULL,0);
|
|
while(raxNext(&ri)) {
|
|
- user *u = ri.data;
|
|
+ rduser *u = ri.data;
|
|
/* Return information in the configuration file format. */
|
|
sds user = sdsnew("user ");
|
|
user = sdscatsds(user,u->name);
|
|
@@ -1641,8 +1641,8 @@
|
|
* before applying to an existing user or creating a new user. If all
|
|
* arguments are valid the user parameters will all be applied together.
|
|
* If there are any errors then none of the changes will be applied. */
|
|
- user *tempu = ACLCreateUnlinkedUser();
|
|
- user *u = ACLGetUserByName(username,sdslen(username));
|
|
+ rduser *tempu = ACLCreateUnlinkedUser();
|
|
+ rduser *u = ACLGetUserByName(username,sdslen(username));
|
|
if (u) ACLCopyUser(tempu, u);
|
|
|
|
for (int j = 3; j < c->argc; j++) {
|
|
@@ -1675,7 +1675,7 @@
|
|
|
|
for (int j = 2; j < c->argc; j++) {
|
|
sds username = c->argv[j]->ptr;
|
|
- user *u;
|
|
+ rduser *u;
|
|
if (raxRemove(Users,(unsigned char*)username,
|
|
sdslen(username),
|
|
(void**)&u))
|
|
@@ -1686,7 +1686,7 @@
|
|
}
|
|
addReplyLongLong(c,deleted);
|
|
} else if (!strcasecmp(sub,"getuser") && c->argc == 3) {
|
|
- user *u = ACLGetUserByName(c->argv[2]->ptr,sdslen(c->argv[2]->ptr));
|
|
+ rduser *u = ACLGetUserByName(c->argv[2]->ptr,sdslen(c->argv[2]->ptr));
|
|
if (u == NULL) {
|
|
addReplyNull(c);
|
|
return;
|
|
@@ -1746,7 +1746,7 @@
|
|
raxStart(&ri,Users);
|
|
raxSeek(&ri,"^",NULL,0);
|
|
while(raxNext(&ri)) {
|
|
- user *u = ri.data;
|
|
+ rduser *u = ri.data;
|
|
if (justnames) {
|
|
addReplyBulkCBuffer(c,u->name,sdslen(u->name));
|
|
} else {
|
|
diff -uNr redis-6.0.1/src/config.c redis-6.0.1.mod/src/config.c
|
|
--- redis-6.0.1/src/config.c 2020-05-02 01:10:20.000000000 +0300
|
|
+++ redis-6.0.1.mod/src/config.c 2020-05-13 13:02:29.309037552 +0300
|
|
@@ -1238,7 +1238,7 @@
|
|
raxStart(&ri,Users);
|
|
raxSeek(&ri,"^",NULL,0);
|
|
while(raxNext(&ri)) {
|
|
- user *u = ri.data;
|
|
+ rduser *u = ri.data;
|
|
sds line = sdsnew("user ");
|
|
line = sdscatsds(line,u->name);
|
|
line = sdscatlen(line," ",1);
|
|
diff -uNr redis-6.0.1/src/module.c redis-6.0.1.mod/src/module.c
|
|
--- redis-6.0.1/src/module.c 2020-05-02 01:10:20.000000000 +0300
|
|
+++ redis-6.0.1.mod/src/module.c 2020-05-13 13:03:22.169208993 +0300
|
|
@@ -366,7 +366,7 @@
|
|
* able to create users, set ACLs to such users, and later authenticate
|
|
* clients using such newly created users. */
|
|
typedef struct RedisModuleUser {
|
|
- user *user; /* Reference to the real redis user */
|
|
+ rduser *user; /* Reference to the real redis user */
|
|
} RedisModuleUser;
|
|
|
|
|
|
@@ -5482,7 +5482,7 @@
|
|
* For expensive authentication operations, it is recommended to block the
|
|
* client and do the authentication in the background and then attach the user
|
|
* to the client in a threadsafe context. */
|
|
-static int authenticateClientWithUser(RedisModuleCtx *ctx, user *user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
|
|
+static int authenticateClientWithUser(RedisModuleCtx *ctx, rduser *user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
|
|
if (user->flags & USER_FLAG_DISABLED) {
|
|
return REDISMODULE_ERR;
|
|
}
|
|
@@ -5521,7 +5521,7 @@
|
|
* See authenticateClientWithUser for information about callback, client_id,
|
|
* and general usage for authentication. */
|
|
int RM_AuthenticateClientWithACLUser(RedisModuleCtx *ctx, const char *name, size_t len, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
|
|
- user *acl_user = ACLGetUserByName(name, len);
|
|
+ rduser *acl_user = ACLGetUserByName(name, len);
|
|
|
|
if (!acl_user) {
|
|
return REDISMODULE_ERR;
|
|
diff -uNr redis-6.0.1/src/networking.c redis-6.0.1.mod/src/networking.c
|
|
--- redis-6.0.1/src/networking.c 2020-05-02 01:10:20.000000000 +0300
|
|
+++ redis-6.0.1.mod/src/networking.c 2020-05-13 13:01:50.424915874 +0300
|
|
@@ -2121,7 +2121,7 @@
|
|
/* CLIENT KILL <ip:port>
|
|
* CLIENT KILL <option> [value] ... <option> [value] */
|
|
char *addr = NULL;
|
|
- user *user = NULL;
|
|
+ rduser *user = NULL;
|
|
int type = -1;
|
|
uint64_t id = 0;
|
|
int skipme = 1;
|
|
diff -uNr redis-6.0.1/src/server.h redis-6.0.1.mod/src/server.h
|
|
--- redis-6.0.1/src/server.h 2020-05-02 01:10:20.000000000 +0300
|
|
+++ redis-6.0.1.mod/src/server.h 2020-05-13 13:01:13.804788502 +0300
|
|
@@ -732,7 +732,7 @@
|
|
no AUTH is needed, and every
|
|
connection is immediately
|
|
authenticated. */
|
|
-typedef struct user {
|
|
+typedef struct rduser {
|
|
sds name; /* The username as an SDS string. */
|
|
uint64_t flags; /* See USER_FLAG_* */
|
|
|
|
@@ -755,7 +755,7 @@
|
|
list *patterns; /* A list of allowed key patterns. If this field is NULL
|
|
the user cannot mention any key in a command, unless
|
|
the flag ALLKEYS is set in the user. */
|
|
-} user;
|
|
+} rduser;
|
|
|
|
/* With multiplexing we need to take per-client state.
|
|
* Clients are taken in a linked list. */
|
|
@@ -780,7 +780,7 @@
|
|
int argc; /* Num of arguments of current command. */
|
|
robj **argv; /* Arguments of current command. */
|
|
struct redisCommand *cmd, *lastcmd; /* Last command executed. */
|
|
- user *user; /* User associated with this connection. If the
|
|
+ rduser *user; /* User associated with this connection. If the
|
|
user is set to NULL the connection can do
|
|
anything (admin). */
|
|
int reqtype; /* Request protocol type: PROTO_REQ_* */
|
|
@@ -1851,7 +1851,7 @@
|
|
|
|
/* acl.c -- Authentication related prototypes. */
|
|
extern rax *Users;
|
|
-extern user *DefaultUser;
|
|
+extern rduser *DefaultUser;
|
|
void ACLInit(void);
|
|
/* Return values for ACLCheckUserCredentials(). */
|
|
#define ACL_OK 0
|
|
@@ -1861,19 +1861,19 @@
|
|
int ACLCheckUserCredentials(robj *username, robj *password);
|
|
int ACLAuthenticateUser(client *c, robj *username, robj *password);
|
|
unsigned long ACLGetCommandID(const char *cmdname);
|
|
-user *ACLGetUserByName(const char *name, size_t namelen);
|
|
+rduser *ACLGetUserByName(const char *name, size_t namelen);
|
|
int ACLCheckCommandPerm(client *c, int *keyidxptr);
|
|
-int ACLSetUser(user *u, const char *op, ssize_t oplen);
|
|
+int ACLSetUser(rduser *u, const char *op, ssize_t oplen);
|
|
sds ACLDefaultUserFirstPassword(void);
|
|
uint64_t ACLGetCommandCategoryFlagByName(const char *name);
|
|
int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err);
|
|
char *ACLSetUserStringError(void);
|
|
int ACLLoadConfiguredUsers(void);
|
|
-sds ACLDescribeUser(user *u);
|
|
+sds ACLDescribeUser(rduser *u);
|
|
void ACLLoadUsersAtStartup(void);
|
|
void addReplyCommandCategories(client *c, struct redisCommand *cmd);
|
|
-user *ACLCreateUnlinkedUser();
|
|
-void ACLFreeUserAndKillClients(user *u);
|
|
+rduser *ACLCreateUnlinkedUser();
|
|
+void ACLFreeUserAndKillClients(rduser *u);
|
|
void addACLLogEntry(client *c, int reason, int keypos, sds username);
|
|
|
|
/* Sorted sets data type */
|