From f99e0f59efeea13cc91af680f21571a62286e163 Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 23 Jan 2019 16:59:09 +0100 Subject: [PATCH] ACL: populate category flags from command table. --- src/acl.c | 14 ++++++++++++- src/server.c | 56 +++++++++++++++++++++++++++++++++++++--------------- src/server.h | 1 + 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/acl.c b/src/acl.c index 8e1ad76b..131507d7 100644 --- a/src/acl.c +++ b/src/acl.c @@ -63,7 +63,8 @@ struct ACLCategoryItem { {"dangerous", CMD_CATEGORY_DANGEROUS}, {"connection", CMD_CATEGORY_CONNECTION}, {"transaction", CMD_CATEGORY_TRANSACTION}, - {"scripting", CMD_CATEGORY_SCRIPTING} + {"scripting", CMD_CATEGORY_SCRIPTING}, + {"",0} /* Terminator. */ }; /* ============================================================================= @@ -116,6 +117,17 @@ int time_independent_strcmp(char *a, char *b) { * Low level ACL API * ==========================================================================*/ +/* Given the category name the command returns the corresponding flag, or + * zero if there is no match. */ +uint64_t ACLGetCommandCategoryFlagByName(const char *name) { + for (int j = 0; ACLCommandCategories[j].flag != 0; j++) { + if (!strcasecmp(name,ACLCommandCategories[j].name)) { + return ACLCommandCategories[j].flag; + } + } + return 0; /* No match. */ +} + /* Method for passwords/pattern comparison used for the user->passwords list * so that we can search for items with listSearchKey(). */ int ACLListMatchSds(void *a, void *b) { diff --git a/src/server.c b/src/server.c index 42cf9578..1df63f65 100644 --- a/src/server.c +++ b/src/server.c @@ -2875,23 +2875,47 @@ int populateCommandTableParseFlags(struct redisCommand *c, char *strflags) { for (int j = 0; j < argc; j++) { char *flag = argv[j]; - if (!strcasecmp(flag,"write")) c->flags |= CMD_WRITE; - else if (!strcasecmp(flag,"read-only")) c->flags |= CMD_READONLY; - else if (!strcasecmp(flag,"use-memory")) c->flags |= CMD_DENYOOM; - else if (!strcasecmp(flag,"admin")) c->flags |= CMD_ADMIN; - else if (!strcasecmp(flag,"pub-sub")) c->flags |= CMD_PUBSUB; - else if (!strcasecmp(flag,"no-script")) c->flags |= CMD_NOSCRIPT; - else if (!strcasecmp(flag,"random")) c->flags |= CMD_RANDOM; - else if (!strcasecmp(flag,"to-sort")) c->flags |= CMD_SORT_FOR_SCRIPT; - else if (!strcasecmp(flag,"ok-loading")) c->flags |= CMD_LOADING; - else if (!strcasecmp(flag,"ok-stale")) c->flags |= CMD_STALE; - else if (!strcasecmp(flag,"no-monitor")) c->flags |= CMD_SKIP_MONITOR; - else if (!strcasecmp(flag,"cluster-asking")) c->flags |= CMD_ASKING; - else if (!strcasecmp(flag,"fast")) c->flags |= CMD_FAST; - else { - sdsfreesplitres(argv,argc); - return C_ERR; + if (!strcasecmp(flag,"write")) { + c->flags |= CMD_WRITE|CMD_CATEGORY_WRITE; + } else if (!strcasecmp(flag,"read-only")) { + c->flags |= CMD_READONLY|CMD_CATEGORY_READ; + } else if (!strcasecmp(flag,"use-memory")) { + c->flags |= CMD_DENYOOM; + } else if (!strcasecmp(flag,"admin")) { + c->flags |= CMD_ADMIN|CMD_CATEGORY_ADMIN|CMD_CATEGORY_DANGEROUS; + } else if (!strcasecmp(flag,"pub-sub")) { + c->flags |= CMD_PUBSUB|CMD_CATEGORY_PUBSUB; + } else if (!strcasecmp(flag,"no-script")) { + c->flags |= CMD_NOSCRIPT; + } else if (!strcasecmp(flag,"random")) { + c->flags |= CMD_RANDOM; + } else if (!strcasecmp(flag,"to-sort")) { + c->flags |= CMD_SORT_FOR_SCRIPT; + } else if (!strcasecmp(flag,"ok-loading")) { + c->flags |= CMD_LOADING; + } else if (!strcasecmp(flag,"ok-stale")) { + c->flags |= CMD_STALE; + } else if (!strcasecmp(flag,"no-monitor")) { + c->flags |= CMD_SKIP_MONITOR; + } else if (!strcasecmp(flag,"cluster-asking")) { + c->flags |= CMD_ASKING; + } else if (!strcasecmp(flag,"fast")) { + c->flags |= CMD_FAST | CMD_CATEGORY_FAST; + } else { + /* Parse ACL categories here if the flag name starts with @. */ + uint64_t catflag; + if (flag[0] == '@' && + (catflag = ACLGetCommandCategoryFlagByName(flag+1)) != 0) + { + c->flags |= catflag; + } else { + sdsfreesplitres(argv,argc); + return C_ERR; + } } + + /* If it's not @fast is @slow in this binary world. */ + if (!(c->flags & CMD_CATEGORY_FAST)) c->flags |= CMD_CATEGORY_SLOW; } sdsfreesplitres(argv,argc); return C_OK; diff --git a/src/server.h b/src/server.h index 51d3a10e..1e38b8ae 100644 --- a/src/server.h +++ b/src/server.h @@ -1736,6 +1736,7 @@ user *ACLGetUserByName(const char *name, size_t namelen); int ACLCheckCommandPerm(client *c); int ACLSetUser(user *u, const char *op, ssize_t oplen); sds ACLDefaultUserFirstPassword(void); +uint64_t ACLGetCommandCategoryFlagByName(const char *name); /* Sorted sets data type */