mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
ACL: ACLCheckCommandPerm() implementation WIP.
This commit is contained in:
parent
733438fe23
commit
a2e376ba52
34
src/acl.c
34
src/acl.c
@ -229,15 +229,41 @@ user *ACLGetUserByName(const char *name, size_t namelen) {
|
||||
* If the user can execute the command C_OK is returned, otherwise
|
||||
* C_ERR is returned. */
|
||||
int ACLCheckCommandPerm(client *c) {
|
||||
user *u = c->user;
|
||||
uint64_t id = c->cmd->id;
|
||||
|
||||
/* If there is no associated user, the connection can run anything. */
|
||||
if (c->user == NULL) return C_OK;
|
||||
if (u == NULL) return C_OK;
|
||||
|
||||
/* We have to deny every command with an ID that overflows the Redis
|
||||
* internal structures. Very unlikely to happen. */
|
||||
if (c->cmd->id >= USER_MAX_COMMAND_BIT) return C_ERR;
|
||||
|
||||
/* Check if the user can execute this command. */
|
||||
if (!(c->user->flags & USER_FLAG_ALLCOMMANDS)) {
|
||||
if (!(u->flags & USER_FLAG_ALLCOMMANDS)) {
|
||||
uint64_t wordid = id / sizeof(u->allowed_commands[0]) / 8;
|
||||
uint64_t bit = 1 << (id % (sizeof(u->allowed_commands[0] * 8)));
|
||||
/* If the bit is not set we have to check further, in case the
|
||||
* command is allowed just with that specific subcommand. */
|
||||
if (!(u->allowed_commands[wordid] & bit)) {
|
||||
/* Check if the subcommand matches. */
|
||||
if (u->allowed_subcommands == NULL || c->argc < 2) return C_ERR;
|
||||
long subid = 0;
|
||||
while (1) {
|
||||
if (u->allowed_subcommands[id][subid] == NULL) return C_ERR;
|
||||
if (!strcasecmp(c->argv[1]->ptr,
|
||||
u->allowed_subcommands[id][subid]))
|
||||
break; /* Subcommand match found. Stop here. */
|
||||
subid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user can execute touch this keys. */
|
||||
if (!(c->user->flags & USER_FLAG_ALLKEYS)) {
|
||||
/* Check if the user can execute commands explicitly touching the keys
|
||||
* mentioned in the command arguments. */
|
||||
if (!(c->user->flags & USER_FLAG_ALLKEYS) &&
|
||||
(c->cmd->getkeys_proc || c->cmd->firstkey))
|
||||
{
|
||||
}
|
||||
|
||||
/* If we survived all the above checks, the user can execute the
|
||||
|
@ -710,7 +710,8 @@ 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. */
|
||||
#define USER_MAX_COMMAND_BIT 1024
|
||||
#define USER_MAX_COMMAND_BIT 1024 /* The first *not valid* bit that
|
||||
would overflow. So check for >= */
|
||||
#define USER_FLAG_ENABLED (1<<0) /* The user is active. */
|
||||
#define USER_FLAG_ALLKEYS (1<<1) /* The user can mention any key. */
|
||||
#define USER_FLAG_ALLCOMMANDS (1<<2) /* The user can run all commands. */
|
||||
|
Loading…
Reference in New Issue
Block a user