mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
ACL LOG: data structures and initial functions.
This commit is contained in:
parent
7ef2270ee7
commit
3e9e27e98f
51
src/acl.c
51
src/acl.c
@ -49,6 +49,8 @@ list *UsersToLoad; /* This is a list of users found in the configuration file
|
|||||||
array of SDS pointers: the first is the user name,
|
array of SDS pointers: the first is the user name,
|
||||||
all the remaining pointers are ACL rules in the same
|
all the remaining pointers are ACL rules in the same
|
||||||
format as ACLSetUser(). */
|
format as ACLSetUser(). */
|
||||||
|
list *ACLLog; /* Our security log, the user is able to inspect that
|
||||||
|
using the ACL LOG command .*/
|
||||||
|
|
||||||
struct ACLCategoryItem {
|
struct ACLCategoryItem {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -920,6 +922,7 @@ void ACLInitDefaultUser(void) {
|
|||||||
void ACLInit(void) {
|
void ACLInit(void) {
|
||||||
Users = raxNew();
|
Users = raxNew();
|
||||||
UsersToLoad = listCreate();
|
UsersToLoad = listCreate();
|
||||||
|
ACLLog = listCreate();
|
||||||
ACLInitDefaultUser();
|
ACLInitDefaultUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1034,7 +1037,7 @@ user *ACLGetUserByName(const char *name, size_t namelen) {
|
|||||||
* command cannot be executed because the user is not allowed to run such
|
* 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
|
* 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 ACLCheckCommandPerm(client *c, int *keyidxptr) {
|
||||||
user *u = c->user;
|
user *u = c->user;
|
||||||
uint64_t id = c->cmd->id;
|
uint64_t id = c->cmd->id;
|
||||||
|
|
||||||
@ -1094,6 +1097,7 @@ int ACLCheckCommandPerm(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
if (keyidxptr) *keyidxptr = keyidx[j];
|
||||||
getKeysFreeResult(keyidx);
|
getKeysFreeResult(keyidx);
|
||||||
return ACL_DENIED_KEY;
|
return ACL_DENIED_KEY;
|
||||||
}
|
}
|
||||||
@ -1454,6 +1458,51 @@ void ACLLoadUsersAtStartup(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
* ACL log
|
||||||
|
* ==========================================================================*/
|
||||||
|
|
||||||
|
#define ACL_LOG_CTX_TOPLEVEL 0
|
||||||
|
#define ACL_LOG_CTX_LUA 1
|
||||||
|
#define ACL_LOG_CTX_MULTI 2
|
||||||
|
|
||||||
|
/* This structure defines an entry inside the ACL log. */
|
||||||
|
typedef struct aclLogEntry {
|
||||||
|
uint64_t count; /* Number of times this happened recently. */
|
||||||
|
int reason; /* Reason for denying the command. ACL_DENIED_*. */
|
||||||
|
int context; /* Toplevel, Lua or MULTI/EXEC? ACL_LOG_CTX_*. */
|
||||||
|
sds object; /* The key name or command name. */
|
||||||
|
sds username; /* User the client is authenticated with. */
|
||||||
|
mstime_t ctime; /* Milliseconds time of last update to this entry. */
|
||||||
|
sds cinfo; /* Client info (last client if updated). */
|
||||||
|
} aclLogEntry;
|
||||||
|
|
||||||
|
void addACLLogEntry(client *c, int reason, int keypos) {
|
||||||
|
/* Create a new entry. */
|
||||||
|
struct aclLogEntry *le = zmalloc(sizeof(*le));
|
||||||
|
le->count = 1;
|
||||||
|
le->object = (reason == ACL_DENIED_CMD) ? sdsnew(c->cmd->name) :
|
||||||
|
sdsdup(c->argv[keypos]->ptr);
|
||||||
|
le->username = sdsdup(c->user->name);
|
||||||
|
le->ctime = mstime();
|
||||||
|
|
||||||
|
client *realclient = c;
|
||||||
|
if (realclient->flags & CLIENT_LUA) realclient = server.lua_caller;
|
||||||
|
|
||||||
|
le->cinfo = catClientInfoString(sdsempty(),realclient);
|
||||||
|
if (c->flags & CLIENT_MULTI) {
|
||||||
|
le->context = ACL_LOG_CTX_MULTI;
|
||||||
|
} else if (c->flags & CLIENT_LUA) {
|
||||||
|
le->context = ACL_LOG_CTX_LUA;
|
||||||
|
} else {
|
||||||
|
le->context = ACL_LOG_CTX_TOPLEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add it to our list of entires. We'll have to trim the list
|
||||||
|
* to its maximum size. */
|
||||||
|
listAddNodeHead(ACLLog, le);
|
||||||
|
}
|
||||||
|
|
||||||
/* =============================================================================
|
/* =============================================================================
|
||||||
* ACL related commands
|
* ACL related commands
|
||||||
* ==========================================================================*/
|
* ==========================================================================*/
|
||||||
|
@ -177,7 +177,7 @@ void execCommand(client *c) {
|
|||||||
must_propagate = 1;
|
must_propagate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int acl_retval = ACLCheckCommandPerm(c);
|
int acl_retval = ACLCheckCommandPerm(c,NULL);
|
||||||
if (acl_retval != ACL_OK) {
|
if (acl_retval != ACL_OK) {
|
||||||
addReplyErrorFormat(c,
|
addReplyErrorFormat(c,
|
||||||
"-NOPERM ACLs rules changed between the moment the "
|
"-NOPERM ACLs rules changed between the moment the "
|
||||||
|
@ -606,7 +606,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check the ACLs. */
|
/* Check the ACLs. */
|
||||||
int acl_retval = ACLCheckCommandPerm(c);
|
int acl_retval = ACLCheckCommandPerm(c,NULL);
|
||||||
if (acl_retval != ACL_OK) {
|
if (acl_retval != ACL_OK) {
|
||||||
if (acl_retval == ACL_DENIED_CMD)
|
if (acl_retval == ACL_DENIED_CMD)
|
||||||
luaPushError(lua, "The user executing the script can't run this "
|
luaPushError(lua, "The user executing the script can't run this "
|
||||||
|
@ -3377,7 +3377,7 @@ int processCommand(client *c) {
|
|||||||
|
|
||||||
/* Check if the user can run this command according to the current
|
/* Check if the user can run this command according to the current
|
||||||
* ACLs. */
|
* ACLs. */
|
||||||
int acl_retval = ACLCheckCommandPerm(c);
|
int acl_retval = ACLCheckCommandPerm(c,NULL);
|
||||||
if (acl_retval != ACL_OK) {
|
if (acl_retval != ACL_OK) {
|
||||||
flagTransaction(c);
|
flagTransaction(c);
|
||||||
if (acl_retval == ACL_DENIED_CMD)
|
if (acl_retval == ACL_DENIED_CMD)
|
||||||
|
@ -1824,7 +1824,7 @@ int ACLCheckUserCredentials(robj *username, robj *password);
|
|||||||
int ACLAuthenticateUser(client *c, robj *username, robj *password);
|
int ACLAuthenticateUser(client *c, robj *username, robj *password);
|
||||||
unsigned long ACLGetCommandID(const char *cmdname);
|
unsigned long ACLGetCommandID(const char *cmdname);
|
||||||
user *ACLGetUserByName(const char *name, size_t namelen);
|
user *ACLGetUserByName(const char *name, size_t namelen);
|
||||||
int ACLCheckCommandPerm(client *c);
|
int ACLCheckCommandPerm(client *c, int *keyidxptr);
|
||||||
int ACLSetUser(user *u, const char *op, ssize_t oplen);
|
int ACLSetUser(user *u, const char *op, ssize_t oplen);
|
||||||
sds ACLDefaultUserFirstPassword(void);
|
sds ACLDefaultUserFirstPassword(void);
|
||||||
uint64_t ACLGetCommandCategoryFlagByName(const char *name);
|
uint64_t ACLGetCommandCategoryFlagByName(const char *name);
|
||||||
|
Loading…
Reference in New Issue
Block a user